﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network.GameClient;
using Rappelz.GameServer.Network;

namespace Rappelz.GameServer
{
    public class Skill
    {
// UserDefinedType: StructSkill
// VTable         :   , Type:  *
        public enum SkillStatus : int
        {
            Idle = 0,
            Cast = 1,
            Fire = 2,
            Complete = 3,
        }
// Function       :   public static struct StructSkill * StructSkill::AllocSkill(struct StructCreature *, int, int)
// Function       :   public void StructSkill::FreeSkill()

        public Skill(Skill rhs)
        {
            this.m_targetPos.z = 0.0f;
            this.m_targetPos.y = 0.0f;
            this.m_targetPos.x = 0.0f;
            this.m_targetPos.face = 0.0f;
            this.m_RushPos.z = 0.0f;
            this.m_RushPos.y = 0.0f;
            this.m_RushPos.x = 0.0f;
            this.m_RushPos.face = 0.0f;
            this.m_Owner = rhs.m_Owner;
            this.m_nSkillUID = rhs.m_nSkillUID;
            this.m_nSkillId = rhs.m_nSkillId;
            this.m_nEnhance = rhs.m_nEnhance;
            this.m_nSkillLevel = rhs.m_nSkillLevel;
            this.m_nSkillLevelAdd = rhs.m_nSkillLevelAdd;
            this.m_SkillBase = rhs.m_SkillBase;
            this.m_bMultiple = rhs.m_bMultiple;
            this.m_nRequestedSkillLevel = rhs.m_nRequestedSkillLevel;
            this.m_bNeedUpdateToDB = false;
            this.m_nAuraMPDecTime = 0;
            this.m_nNextCoolTime = 0;
            this.m_nErrorCode = 0;
            this.m_Status = 0;
            this.m_nCastTime = 0;
            this.m_nCastingDelay = 0;
            this.m_nFireTime = 0;
            this.m_nCurrentFire = 0;
            this.m_nTotalFire = 0;
            this.m_nTargetCount = 1;
            this.m_nFireCount = 1;
//            XSEH::IncreaseAllocCount("StructSkill", 0);

        }

        public Skill(Creature pOwner, int uid, int id)
        {
            this.m_targetPos.z = 0.0f;
            this.m_targetPos.y = 0.0f;
            this.m_targetPos.x = 0.0f;
            this.m_targetPos.face = 0.0f;
            this.m_RushPos.z = 0.0f;
            this.m_RushPos.y = 0.0f;
            this.m_RushPos.x = 0.0f;
            this.m_RushPos.face = 0.0f;
            this.m_Owner = pOwner;
            this.m_nSkillUID = uid;
            this.m_nEnhance = 0;
            this.m_nSkillLevel = 0;
            this.m_nSkillLevelAdd = 0;
            this.m_bNeedUpdateToDB = false;
            this.m_bMultiple = false;
            this.m_nAuraMPDecTime = 0;
            this.m_nNextCoolTime = 0;
            this.m_nAuraRefreshTime = 0;
            this.m_nSkillId = id;
            this.bindSkillInfo(id);
            this.Init();
//            XSEH::IncreaseAllocCount("StructSkill", 1);
        }


// Function       :   public void StructSkill::~StructSkill()
// Function       :   public int GetSkillUID()
// Function       :   public bool IsPassiveSkill()
// Function       :   public void SetEnhance(int)
// Function       :   public int GetEnhance()
// Function       :   public int GetSkillId()
// Function       :   public int GetToggleGroup()
// Function       :   public int GetBaseSkillLevel()
// Function       :   public int GetCurrentSkillLevel()
// Function       :   public void SetBaseSkillLevel(int)
// Function       :   public int GetRequestedSkillLevel()

        public void SetRequestedSkillLevel(int nLevel)
        {
            int tl = this.m_nSkillLevel + this.m_nSkillLevelAdd;
            if (nLevel <= tl)
                tl = nLevel;
            this.m_nRequestedSkillLevel = tl;
        }
// Function       :   public class c_fixed<10000> StructSkill::GetVar(int)
// Function       :   public const struct SkillBase * GetSkillBase()

        public bool Cancel()
        {
            return true;
        }
// Function       :   public unsigned long GetAuraMPDecTime()
// Function       :   public void SetAuraMPDecTime(unsigned long)
// Function       :   public unsigned long GetAuraRefreshTime()
// Function       :   public void SetAuraRefreshTime(unsigned long)

        public bool CheckCoolTime(uint t)
        {
            bool result;

            if (GameRule.bNoSkillCooltime)
                result = true;
            else
                result = this.m_nNextCoolTime < t;
            return result;
        }

        public uint GetSkillCoolTime()
        {
            int l;

            if (this.m_Owner.IsSummon())
                l = this.m_nRequestedSkillLevel;
            else
                l = this.m_nEnhance;
            return (uint)(this.m_Owner.GetCoolTimeSpeed() * (float)(this.m_Owner.GetCoolTimeMod((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0) * this.m_SkillBase.GetCoolTime(l)));
        }

        public void SetRemainCoolTime(uint time)
        {
            this.m_nNextCoolTime = time + Globals.GetArTime();
        }
// Function       :   public unsigned long GetRemainCoolTime(unsigned long)
// Function       :   public void StructSkill::onDamage(int)
// Function       :   public unsigned int GetTargetHandle()
// Function       :   public struct ArPosition GetTargetPosition()
// Function       :   public unsigned long GetCastingTime()
// Function       :   public unsigned long GetOriginalCastingDelay()

        public int Cast(int nSkillLevel, uint handle, ArPosition pos, byte layer, bool bIsCastedByItem)
        {
            ArPosition targetPos;               // -212 -0D4h
            ArPosition myPos;                   // -196 -0C4h
            uint current_time;                  // 16   10h
            int nHP;                            // 40   28h
            float fCostHP;                      // 48   30h
            float fMP;                            // 60   3Ch
            float mana_cost;                      // 64   40h
            uint delay;                         // 68   44h
            int decMP;                          // 76   4Ch
            float fCostSP;                      // 76   4Ch
            float fCostMP = 0.0f;                      // 80   50h
            Summon pSummon = null;              // 80   50h
            int nCurrentHavocPercentage;        // 80   50h
            FieldProp pProp;                    // 96   60h
            int nEnergy;                        // 96   60h
            int decHP;                          // 108  6Ch
            int nTameItemCode;                  // 108  6Ch
            int nCurrentHPPercentage;           // 108  6Ch
            uint nOriginalCastingDelay;         // 108  6Ch
            int nTargetCreatureGroup;           // 108  6Ch
            float nMinDistance;                 // 108  6Ch
            float fCostEnergy;                  // 108  6Ch
            int nErrorCode;                     // 120  78h

            Creature cr = null;
            Monster mob = null;
            Summon summon = null;
            Item item = null;
            Player player = this.m_Owner as Player;
            int i;
            float cmp1;
            float cmp2;
            float cmp3;
            int tv1;
            int tv2;
            int tv3;


            current_time = Globals.GetArTime();
            delay = 0xffffffff;

            if (this.m_nSkillLevel + this.m_nSkillLevelAdd < nSkillLevel)
                nSkillLevel = this.m_nSkillLevel + this.m_nSkillLevelAdd;
            this.SetRequestedSkillLevel(nSkillLevel);
            mana_cost = 0;
            this.m_Status = SkillStatus.Cast;

            if (!this.CheckCoolTime(current_time))
            {
                this.m_nErrorCode = 22;
                goto PROCESS;
            }

            if (this.m_SkillBase.vf_is_not_need_weapon == 0)
            {
                bool weaponOk = false;
                if (this.m_SkillBase.vf_shield_only != 0)
                {
                    weaponOk = this.m_Owner.IsWearShield();
                }
                else
                {
                    weaponOk = this.m_SkillBase.IsUseableWeapon(this.m_Owner.GetWeaponClass());
                }
                if (!weaponOk)
                {
                    this.m_nErrorCode = 23;
                    goto PROCESS;
                }
            }

            if (this.m_SkillBase.uid == (int)SkillBase.SkillId.CreatureTaming || this.m_SkillBase.uid == (int)SkillBase.SkillId.PetTaming)
            {
                if (!this.m_Owner.IsPlayer())
                    goto LABEL_106;
                player = this.m_Owner as Player;
                cr = Creature.get(handle) as Creature;
                if (cr == null || !cr.IsMonster())
                    goto LABEL_106;

                mob = cr as Monster;
                nTameItemCode = mob.GetTameItemCode();
                if(nTameItemCode == 0 || mob.GetTamer() != 0)
                    goto LABEL_106;

                if (mob.m_nHP != mob.m_nMaxHP )
                {
                    this.m_nErrorCode = 20;
                    goto PROCESS;
                }

                if (this.m_SkillBase.uid == (int)SkillBase.SkillId.CreatureTaming)
                {
                    item = player.FindEmptySummonCard(nTameItemCode);
                    if (item == null)
                        goto LABEL_106;

                    if (player.m_hTamingTarget != 0)
                    {
                        this.m_nErrorCode = 70;
                        goto PROCESS;
                    }
                }
                else
                {
                    if (this.m_SkillBase.uid == (int)SkillBase.SkillId.PetTaming
                      && !mob.IsEnvironmentMonster()
                      || !mob.IsEnvironmentMonster()
                      || mob.GetTameCode() == 0
                      || Item.GetItemBase(nTameItemCode).nGroup != 18
                      || player.FindEmptyPetCage(nTameItemCode) == null)
                        goto LABEL_106;

//                     if (this.m_SkillBase.uid != (int)SkillBase.SkillId.PetTaming
//                       || mob.IsEnvironmentMonster()
//                       && mob.IsEnvironmentMonster()
//                       && mob.GetTameCode() != 0
//                       && Item.GetItemBase(nTameItemCode).nGroup == 18
//                       && player.FindEmptyPetCage(nTameItemCode) != null)
//                         goto LABEL_127;
                }
            }
            else if (this.m_SkillBase.uid == (int)SkillBase.SkillId.Shoveling)
            {
                if(!this.m_Owner.IsPet())
                    goto LABEL_106;
            }
            else if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.Summon)
            {
                item = Item.FindItem(handle);

                if (!this.m_Owner.IsPlayer()
                  || player.m_pSubSummon != null
                  || !player.m_bIsSummonable
                  || item == null
                  || item.m_pItemBase.nGroup != 13
                  || item.m_Instance.OwnerHandle != this.m_Owner.m_hHandle)
                    goto LABEL_106;
                if (this.m_Owner.IsPlayer())
                {
                    i = 0;
                    while (item.m_hHandle != player.m_aBindSummonCard[i].m_hHandle)
                    {
                        ++i;
                        if (i >= 6)
                            goto LABEL_106;
                    }
                }
                pSummon = item.m_pSummon;
                if (pSummon == null)
                {
                    this.m_nErrorCode = 1;
                    goto PROCESS;
                }
                if (pSummon.bIsInWorld )
                    goto LABEL_106;
                if (GameRule.bLimitDungeonEnterableLevel)
                {
                    if (DungeonManager.Instance.GetDungeonID(this.m_Owner.mv.x, this.m_Owner.mv.y) != 0)
                    {
                        if (pSummon.GetLevel() > this.m_Owner.GetLevel())
                        {
                            this.m_nErrorCode = 16;
                            goto PROCESS;
                        }
                    }
                }
                ArPosition tmpPos = this.m_Owner.GetCurrentPosition(current_time);
                pSummon.SetCurrentXY(tmpPos.x,tmpPos.y);
                pSummon.m_layer = this.m_Owner.m_layer;
                pSummon.StopMove();
                do
                {
                    do
                    {
                        pSummon.AddNoise(Globals.GetRandomInt32(), Globals.GetRandomInt32(),70);
                        this.m_targetPos = pSummon.GetCurrentPosition(current_time);
                        this.m_targetLayer = pSummon.m_layer;
                    }
                    while (pos.x == this.m_targetPos.x && pos.y == this.m_targetPos.y);
                }
                while (tmpPos.GetDistance(this.m_targetPos) < 24.0f);
                goto LABEL_127;
            }
            else if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.Unsummon
                 || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.UnsummonAndAddState)
            {
                if (!this.m_Owner.IsPlayer() || player.m_pMainSummon == null)
                    goto LABEL_106;
                goto LABEL_127;
            }
            else if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicSingleDamageOrDeath)
            {
                cr = Creature.get(handle) as Creature;
                if (cr == null || !cr.IsMonster())
                    goto LABEL_106;

                mob = cr as Monster;

                if (this.m_SkillBase.m_var[8] != mob.GetCreatureGroup())
                {
                    this.m_nErrorCode = 24;
                    goto PROCESS;
                }

                if (!mob.IsMonster() || this.m_SkillBase.m_var[9] < mob.m_pContentInfo.monster_type)
                    goto LABEL_106;

            }
            else if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddStateByTargetType)
            {

                cr = Creature.get(handle) as Creature;
                if (cr == null)
                    goto LABEL_106;

                nTargetCreatureGroup = cr.GetCreatureGroup();
                if (nTargetCreatureGroup != 99)
                {
                    i = 5;
                    while (true)
                    {
                        if (this.m_SkillBase.m_var[i] == nTargetCreatureGroup)
                            break;
                        if (i >= 10)
                        {
                            this.m_nErrorCode = 24;
                            goto PROCESS;
                        }
                    }
                }
            }
            else if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.PhysicalSingleDamageWithShield)
            {
                if (!this.m_Owner.IsWearShield())
                    goto PROCESS;
                goto LABEL_127;
            }
            else if (this.m_SkillBase.effect_type != (int)SkillBase.EffectType.PhysicalSingleDamageRushKnockBackOld
                && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.PhysicalSingleDamageWithoutWeapnRushKnockBack
                && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.PhysicalSingleDamageRush
                && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.PhysicalSingleDamageRushKnockback)
            {
                if (this.m_SkillBase.effect_type != (int)SkillBase.EffectType.ActivateFieldProp
                    && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.RegionHealByFieldProp
                    && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.AreaAffectHealByHieldProp)
                {
                    if (this.m_SkillBase.effect_type != (int)SkillBase.EffectType.MagicalSingleDamageByConsumingTargetsState
                        && this.m_SkillBase.effect_type != (int)SkillBase.EffectType.PhysicalSingleDamageByConsumingTargetsState)
                    {
                        if (this.m_SkillBase.effect_type != (int)SkillBase.EffectType.RespawnMonsterNear)
                            goto LABEL_127;
                        if (!this.m_Owner.IsMonster())
                            goto LABEL_106;

                        goto LABEL_127;
                    }
                    cr = Creature.get(handle) as Creature;
                    if (cr == null)
                    {
                        this.m_nErrorCode = 5;
                        goto PROCESS;
                    }

                    i = 0;
                    while (true)
                    {
                        if (cr.GetState((State.StateCode)this.m_SkillBase.m_var[i]) != null)
                            break;
                        ++i;
                        if (i >= 4)
                            goto LABEL_106;
                    }
                    goto LABEL_127;
                }
                if (this.m_Owner.IsPlayer())
                {
                    pProp = GameObject.get(handle) as FieldProp;
                    if (pProp != null && pProp.m_pFieldPropBase.nActivateSkillId == this.m_SkillBase.uid)
                    {
                        if (pProp.m_nUseCount >= 1 && pProp.IsUsable(this.m_Owner as Player))
                        {
                            delay = pProp.GetCastingDelay();
                            goto LABEL_127;
                        }
                    }
                    this.m_nErrorCode = 5;
                    goto PROCESS;
                }
                this.m_nErrorCode = 5;
                goto PROCESS;
            }

            cr = Creature.get(handle) as Creature;
            if (cr == null)
            {
                goto LABEL_106;
            }
            myPos = this.m_Owner.GetCurrentPosition(current_time);
            targetPos = cr.GetCurrentPosition(current_time);

            if (this.m_SkillBase.effect_type >= (int)SkillBase.EffectType.PhysicalSingleDamageWithoutWeapnRushKnockBack)
            {
                if (this.m_SkillBase.effect_type <= (int)SkillBase.EffectType.PhysicalSingleDamageRushKnockBackOld)
                {
                    nMinDistance = (this.m_SkillBase.m_var[3] * 12);
                    goto LABEL_100;
                }
                if ((this.m_SkillBase.effect_type - (int)SkillBase.EffectType.PhysicalSingleDamageRush) <= 1)
                {
                    nMinDistance = (this.m_SkillBase.m_var[4] * 12);
                    goto LABEL_100;
                }
            }
            nMinDistance = 0.0f;
        LABEL_100:
            if (nMinDistance > myPos.GetDistance(targetPos))
                goto LABEL_106;

            if (!GameContent.CollisionToLine(myPos.x, myPos.y, targetPos.x, targetPos.y))
            {
                goto LABEL_127;
            }
            goto LABEL_106;

/////////////////////////
// main processing section
/////////////////////////
            
        LABEL_127:
            nHP = this.m_Owner.m_nHP;
            fMP = this.m_Owner.m_fMP;
            nEnergy = this.m_Owner.m_nEnergy;

            if (this.m_Owner.m_nMaxHP != 0)
                decHP = 100 * this.m_Owner.m_nHP / this.m_Owner.m_nMaxHP;
            else
                decHP = 0;

            if (this.m_Owner.m_nMaxMP != 0)
                decMP = 100 * (int)this.m_Owner.m_fMP / this.m_Owner.m_nMaxMP;
            else
                decMP = 0;

            if (this.m_Owner.m_nMaxHavoc != 0)
                nCurrentHavocPercentage = 100 * this.m_Owner.m_nHavoc / this.m_Owner.m_nMaxHavoc;
            else
                nCurrentHavocPercentage = 0;

            if ((this.m_SkillBase.effect_type == (int)SkillBase.EffectType.ToggleAura
                || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.ToggleDifferentialAura)
                && this.m_Owner.IsActiveAura(this))
            {
                mana_cost = 0;
            }
            else
            {
                cmp1 = this.m_SkillBase.cost_mp + (this.m_nEnhance * this.m_SkillBase.cost_mp_per_enhance) + (this.m_nRequestedSkillLevel * this.m_SkillBase.cost_mp_per_skl);
                cmp2 = (this.m_SkillBase.cost_mp_per_skl_per * this.m_nRequestedSkillLevel) + this.m_SkillBase.cost_mp_per;
                mana_cost = (int)(this.m_Owner.GetManaCostRatio((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0)
                            * (float)(this.m_Owner.m_fMP * cmp2 / 100.0f + cmp1));
            }

            if (this.m_SkillBase.need_hp <= 0)
            {
                if (this.m_SkillBase.need_hp < 0 && decHP > -this.m_SkillBase.need_hp)
                    goto LABEL_106;
            }
            else
            {
                if (decHP < this.m_SkillBase.need_hp)
                {
                    this.m_nErrorCode = 20;
                    goto PROCESS;
                }
            }
            if (decMP < this.m_SkillBase.need_mp)
            {
                this.m_nErrorCode = 21;
                goto PROCESS;
            }

            if (nCurrentHavocPercentage < this.m_SkillBase.need_havoc)
            {
                this.m_nErrorCode = 30;
                goto PROCESS;
            }

            cmp1 = ((this.m_SkillBase.cost_hp_per_skl_per * this.m_nRequestedSkillLevel) + this.m_SkillBase.cost_hp_per) * this.m_Owner.m_nMaxHP;
            cmp2 = this.m_SkillBase.cost_hp + (this.m_nRequestedSkillLevel * this.m_SkillBase.cost_hp_per_skl);
            if (this.m_Owner.m_nHP - 1 < (int)(cmp1 / 100.0f + cmp2))
            {
                this.m_nErrorCode = 20;
                goto PROCESS;
            }
            if (this.m_Owner.m_fMP < mana_cost)
            {
                this.m_nErrorCode = 21;
                goto PROCESS;
            }
            if (nCurrentHavocPercentage < this.m_SkillBase.cost_havoc + this.m_nRequestedSkillLevel * this.m_SkillBase.cost_havoc_per_skl)
            {
                this.m_nErrorCode = 30;
                goto PROCESS;
            }
            if (this.m_Owner.m_nEnergy < this.m_SkillBase.GetCostEnergy(this.m_nRequestedSkillLevel))
            {
                this.m_nErrorCode = 31;
                goto PROCESS;
            }
            if (this.m_Owner.GetLevel() < this.m_SkillBase.need_level)
            {
                this.m_nErrorCode = 13;
                goto PROCESS;
            }
            if (this.m_Owner.GetJobPoint() < this.m_SkillBase.cost_jp + this.m_nEnhance * this.m_SkillBase.cost_jp_per_enhance)
            {
                this.m_nErrorCode = 12;
                goto PROCESS;
            }
            tv1 = this.m_SkillBase.cost_exp + this.m_nEnhance * this.m_SkillBase.cost_exp_per_enhance;
            if (tv1 != 0)
            {
                if (this.m_Owner.m_nEXP < tv1 || this.m_Owner.m_nEXP - tv1 <= GameContent.GetNeedExp(this.m_Owner.GetLevel() - 1))
                {
                    this.m_nErrorCode = 33;
                    goto PROCESS;
                }
            }
            cr = Creature.get(handle) as Creature;

            if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddStateBySelfCost
                || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddRegionStateBySelfCost)
            {
                cmp1 = (float)((this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel) + this.m_SkillBase.m_var[0]);
                fCostHP = (float)((this.m_SkillBase.m_var[2] * this.m_nEnhance) + cmp1);

                cmp1 = (float)(this.m_SkillBase.m_var[4] * this.m_nRequestedSkillLevel);
                fCostSP = (this.m_SkillBase.m_var[5] * this.m_nEnhance) + cmp1;

                cmp1 = (this.m_SkillBase.m_var[7] * this.m_nRequestedSkillLevel);
                fCostEnergy = cmp1 + (this.m_SkillBase.m_var[8] * this.m_nEnhance);

                if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddStateBySelfCost)
                {
                    cmp1 = ((this.m_SkillBase.m_var[10] * this.m_nRequestedSkillLevel) + this.m_SkillBase.m_var[9]);
                    cmp2 = (this.m_SkillBase.m_var[11] * this.m_nEnhance);
                    fCostMP = cmp1 + cmp2;
                }

                if (cr == null || !cr.IsSummon())
                {
                    goto LABEL_106;
                }
                summon = cr as Summon;
                if (fCostHP != 0.0f)
                {
                    if (fCostHP > summon.m_nHP)
                    {
                        this.m_nErrorCode = 20;
                        goto PROCESS;
                    }
                }
                if (fCostSP != 0.0f)
                {
                    if (fCostSP > summon.m_nSP)
                    {
                        this.m_nErrorCode = 36;
                        goto PROCESS;
                    }
                }
                if (fCostEnergy > 0.0f && fCostEnergy > summon.m_nEnergy || fCostEnergy == -1.0f && summon.m_nEnergy == 0)
                {
                    this.m_nErrorCode = 31;
                    goto PROCESS;
                }
                if (fCostMP != 0.0f)
                {
                    if (fCostMP > summon.m_fMP)
                    {
                        this.m_nErrorCode = 21;
                        goto PROCESS;
                    }
                }
            }
//////////////////

        if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicMultipleDamageT1DealSummonHpOld
          || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddHpMpBySummonDamage
          || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddHpMpBySummonDead
          || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddHpMpByStealSummonHpMp
          || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicMultipleDamageDealSummonHp)
        {
            if (!this.m_Owner.IsPlayer())
            {
                this.m_nErrorCode = 20;
                goto PROCESS;
            }
            pSummon = player.m_pMainSummon;
            if (pSummon == null)
            {
                this.m_nErrorCode = 20;
                goto PROCESS;
            }

            fCostHP = 0;
            fCostMP = 0;
            if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicMultipleDamageT1DealSummonHpOld)
            {
                cmp1 = this.m_SkillBase.m_var[6] + (this.m_SkillBase.m_var[7] * this.m_nRequestedSkillLevel);
                cmp2 = (this.m_SkillBase.m_var[8] * this.m_nEnhance);
                fCostHP = cmp1 + cmp2;
            }
            if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicMultipleDamageDealSummonHp)
            {
                cmp1 = this.m_SkillBase.m_var[9] + (this.m_SkillBase.m_var[10] * this.m_nRequestedSkillLevel);
                cmp2 = (this.m_SkillBase.m_var[11] * this.m_nEnhance);
                fCostHP = cmp1 + cmp2;
            }
            if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddHpMpBySummonDamage)
            {
                fCostHP = (this.m_SkillBase.m_var[10] * summon.m_nMaxHP);
            }
            if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AddHpMpByStealSummonHpMp)
            {
                cmp1 = ((this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel) + this.m_SkillBase.m_var[0]);
                cmp2 = (this.m_SkillBase.m_var[4] * this.m_nEnhance);
                fCostHP = cmp1 + cmp2;
                cmp1 = (this.m_SkillBase.m_var[2] + (this.m_SkillBase.m_var[3] * this.m_nRequestedSkillLevel));
                cmp2 = (this.m_SkillBase.m_var[5] * this.m_nEnhance) + cmp1;
                fCostMP = cmp2;
            }
            if (summon.m_nHP < fCostHP + 1)
            {
                this.m_nErrorCode = 20;
                goto PROCESS;
            }
            if (summon.m_fMP < fCostMP)
            {
                this.m_nErrorCode = 21;
                goto PROCESS;
            }
        }
        if (this.m_Owner.IsPet())
        {
            if (this.m_SkillBase.uid == (int)SkillBase.SkillId.Shoveling)
            {
                Pet pet = m_Owner as Pet;
                pet.m_nShovelingStatus = Pet.ShovelingStatus.Search;
                Messages.BroadcastStatusMessage(pet);
            }
        }

        player = null;
        if (this.m_Owner.IsPlayer())
            player = this.m_Owner as Player;
        if (this.m_Owner.IsSummon())
            player = (this.m_Owner as Summon).m_master;
        if (player != null)
        {
            if (this.m_SkillBase.cost_item == 100001)
            {
                item = player.GetWornItem(ItemBase.ItemWearType.WearShield);
                if (item == null || item.m_pItemBase.nGroup != 98
                  || item.m_Instance.nCount < this.m_SkillBase.cost_item_count + this.m_nRequestedSkillLevel * this.m_SkillBase.cost_item_count_per_skl)
                {
                    this.m_nErrorCode = 32;
                    goto PROCESS;
                }
            }
            else
            {
                if (this.m_SkillBase.cost_item != 0)
                {
                    item = player.FindItemByCode(this.m_SkillBase.cost_item);
                    if (item == null
                      || item.m_Instance.nCount < this.m_SkillBase.cost_item_count
                                                 + this.m_nRequestedSkillLevel
                                                 * this.m_SkillBase.cost_item_count_per_skl)
                    {
                        this.m_nErrorCode = 34;
                        goto PROCESS;
                    }
                }
            }
        }


        // check to see if a state is needed
        if (this.m_SkillBase.need_state_id != 0)
        {
            State s = this.m_Owner.GetState((State.StateCode)this.m_SkillBase.need_state_id);
            if (s == null || s.GetLevel() < this.m_SkillBase.need_state_level)
            {
                // we don't have it or it's too low, time to quit
                goto LABEL_106;
            }

            if (this.m_SkillBase.need_state_exhaust != 0)
                this.m_Owner.RemoveState(s.m_nUID);
            // we can continue now
        }

        // see if this is a field prop we are activating
        if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.ActivateFieldProp
            || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.RegionHealByFieldProp
            || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.AreaAffectHealByHieldProp)
        {
            FieldProp fp = GameObject.get(handle) as FieldProp;

            if (fp == null || GameContent.IsVisibleRegion((uint)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                      (uint)(this.m_Owner.mv.y / GameContent.g_nRegionSize),
                      (uint)(fp.mv.x / GameContent.g_nRegionSize), (uint)(fp.mv.y / GameContent.g_nRegionSize)) == 0)
            {
                this.m_nErrorCode = 5;
                goto PROCESS;
            }
            fp.Cast();
        }
        this.m_Owner.SetMP(fMP - mana_cost * 0.2f);

        nOriginalCastingDelay = delay;
        if (delay == 0xffffffff)
        {
            delay = this.m_SkillBase.GetCastDelay(this.m_nRequestedSkillLevel, this.m_nEnhance);

            if (this.m_nSkillUID != -1)
            {
                if (this.m_nSkillUID != -2)
                {
                    if (this.m_nSkillUID != -3)
                    {
                        if (this.m_nSkillUID != -4)
                        {
                            if (this.m_nSkillUID != -5)
                            {
                                if (!bIsCastedByItem)
                                {
                                    if ((int)delay < 0)
                                        delay = (uint)(delay + 4294967296);
                                    delay = (uint)(delay / (this.m_Owner.m_Attribute.nCastingSpeed / 100.0f));
                                    delay = (uint)((float)delay * (this.m_Owner.GetCastingMod((Elemental.Type)this.m_SkillBase.elemental,
                                        this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0,
                                        nOriginalCastingDelay)));
                                }
                            }
                        }
                    }
                }
            }
        }
        if (this.m_SkillBase.effect_type != (int)SkillBase.EffectType.Summon)
        {
            this.m_targetPos.Copy(pos);
            this.m_targetLayer = layer;
        }

        this.m_nCastingDelay = nOriginalCastingDelay;
        this.m_hTarget = handle;
        this.m_nCastTime = current_time;
        this.m_nFireTime = current_time + delay;
        goto PROCESS;
//    }

/////////////
////////////
        LABEL_106:
            this.m_nErrorCode = 5;

        PROCESS:

            // here is where we actually do the skill I guess.

            nErrorCode = this.m_nErrorCode;
            if (this.m_nErrorCode != 0)
            {
                this.Init();
            }
            else
            {
                this.broadcastSkillMessage((int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                    (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize),this.m_Owner.m_layer,0,
                    (int)((float)mana_cost * 0.2f), 1);

                if (this.m_SkillBase.is_harmful != 0)
                {
                    if (this.m_SkillBase.is_spell_act != 0)
                    {
                        mob = Creature.get(handle) as Monster;
                        if (mob != null)
                        {
                            if (mob.IsMonster())
                            {
                                if (mob.IsCastRevenger())
                                {
                                    mob.AddHate(this.m_Owner.m_hHandle, 1, true, true);
                                }
                            }
                        }
                    }
                }
            }
            return nErrorCode;
        }

        public void ProcSkill()
        {
// .text:004D9A22 _fo             = StructSkill::ProcSkill::__l74::_mySkillFunctor ptr -252  -0FCh
            ArPosition pos;                                                         // -232  -0E8h
            ItemBase.ItemWearType[] WeaponIndices = new ItemBase.ItemWearType[2];   // -207  -0D0h
// .text:004D9A22 _lock           = ArcadiaAutoLock ptr -0ACh
// .text:004D9A22 var_94          = qword ptr -94h
            List<ArPosition> vPath = new List<ArPosition>();                        // -140  -8Ch
            ArPosition top_left = new ArPosition();                                 // -124  -7Ch
            ArPosition bottom_right = new ArPosition();                             // -108  -6Ch
            long nItemCostCount;                                                    // -28   -1Ch
            int cost_jp;                                                            //  80    50h
            Creature pTarget;                                                       //  84    54h
// .text:004D9A22 itSkillTarget   = GameObject::iterator ptr                            88    58h
            int cost_hp;                                                            //  96    60h
            uint ct;                                                                //  96    60h
            int decHP;                                                              //  104   68h
            int nSLV;                                                               //  104   68h
            int cost_mp;                                                            //  108   6Ch
            bool bSuccess;                                                          //  112   70h
            float fKnockBackRange;                                                  //  116   74h
            int nEnhance;                                                           //  116   74h
//            int decHP;                                                              //  116   74h

// Data           :   ebp Relative, [FFFFFF54], Local, Type: struct ArcadiaAutoLock, _lock
// Data           :   ebp Relative, [FFFFFF40], Local, Type: struct ArcadiaAutoLock, _lock
// Data           :   ebp Relative, [00000018], Local, Type: struct ArPosition, bottom_right
// Data           :   ebp Relative, [00000028], Local, Type: struct ArPosition, top_left
            RLock rl;
            AutoLock al;
            GameObject objTarget;
            Pet pet = null;
            Player player = null;
            Summon pSummon = null;
            Creature cr = null;
            int i;

            try
            {
                if (this.m_Status != SkillStatus.Idle)
                {
                    ct = Globals.GetArTime();
                    pTarget = null;
                    objTarget = null;

                    rl = RappelzServer.Instance._LockObjectWithVisibleRange(this.m_Owner);
                    al = new AutoLock(rl.handle);

                    if (this.m_Owner.m_nHP == 0)
                    {
                        this.m_Owner.CancelSkill();
                        return;
                    }
                    objTarget = GameObject.get(this.m_hTarget);
                    if (this.m_Status != SkillStatus.Complete)
                    {
                        if (objTarget != null)
                        {
                            if (objTarget.IsCreature())
                            {
                                pTarget = objTarget as Creature;

                                if (pTarget.m_nHP != 0)
                                {
                                    if (this.m_SkillBase.is_corpse != 0)
                                    {
                                        this.m_Owner.CancelSkill();
                                        return;
                                    }
                                }
                                else
                                {
                                    if (this.m_SkillBase.is_corpse == 0)
                                    {
                                        this.m_Owner.CancelSkill();
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    if (this.m_hTarget != 0 && objTarget == null)
                    {
                        this.m_Owner.CancelSkill();
                        return;
                    }

                    if (this.m_Owner.IsPet()
                      && this.m_SkillBase.uid == (int)SkillBase.SkillId.Shoveling
                      && this.m_Status == SkillStatus.Cast)
                    {
                        pet = this.m_Owner as Pet;
                        player = pet.m_master;
                        if (player == null
                          || !player.bIsInWorld
                          || player.mv.GetDistance(pet.mv) > 120.0f)
                        {
                            this.m_Owner.CancelSkill();
                            return;
                        }

                        if (pet.m_nShovelingStatus != Pet.ShovelingStatus.Search)
                        {
                            if (pet.m_nShovelingStatus == Pet.ShovelingStatus.Approach)
                            {
                                if (ct >= this.m_nCastTime + 500)
                                {
                                    pet.m_nShovelingStatus = Pet.ShovelingStatus.Dig;
                                    Messages.BroadcastStatusMessage(pet);
                                }
                            }
                        }
                        else
                        {
                            if (ct >= this.m_nCastTime + 200)
                            {
                                pos = new ArPosition(pet.mv);
                                while (vPath.Count < 2)
                                {
                                    pos.x += ((Globals.GetRandomInt32() % 48) - 24);
                                    pos.y += ((Globals.GetRandomInt32() % 48) - 24);
                                    vPath.Add(pos);
                                }
                                pet.SetMultipleMove(vPath, 75, 0);
                                pet.m_nShovelingStatus = Pet.ShovelingStatus.Approach;
                                Messages.BroadcastStatusMessage(pet);
                                vPath.Clear();
                            }
                        }
                    }
                    if (ct < this.m_nFireTime)
                        return;

                    if (this.m_Status == SkillStatus.Cast)
                    {
                        //                     this.m_Owner.PrepareRemoveExhaustiveSkillStateMod(
                        //                         this.m_SkillBase.is_spell_act == 0,
                        //                         this.m_SkillBase.is_harmful != 0,
                        //                         this.m_SkillBase.elemental,
                        //                         this.m_nCastingDelay);
                        this.m_Status = SkillStatus.Fire;
                    }
                    //                ArcadiaAutoLock::_ArcadiaAutoLock((v1 - 192));
                    //                ArcadiaAutoLock::ArcadiaAutoLock((v1 - 172));
                    if (objTarget != null && objTarget.bIsInWorld)
                    {
                        bottom_right.Reset();
                        top_left.Reset();

                        top_left.x = objTarget.mv.x;
                        if (this.m_Owner.mv.x <= objTarget.mv.x)
                            top_left.x = this.m_Owner.mv.x;

                        top_left.y = objTarget.mv.y;
                        if (this.m_Owner.mv.y <= objTarget.mv.y)
                            top_left.y = this.m_Owner.mv.y;

                        bottom_right.x = objTarget.mv.x;
                        if (objTarget.mv.x <= this.m_Owner.mv.x)
                            bottom_right.x = this.m_Owner.mv.x;

                        bottom_right.y = objTarget.mv.y;
                        if (objTarget.mv.y <= this.m_Owner.mv.y)
                            bottom_right.y = this.m_Owner.mv.y;

                        // test for knockback, need to adjust our size if we are doing one

                        //                     if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.PhysicalSingleDamageKnockbackOld
                        //                         || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.PhysicalSingleRegionDamageKnockbackOld 
                        //                         || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.PhysicalSingleDamageWithoutWeapnRushKnockBack 
                        //                         || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.PhysicalSingleDamageRushKnockBackOld)
                        //                     {
                        //                         if ( !objTarget.IsCreature() || objTarget.IsKnockbackable())
                        //                         {
                        //                             *(v1 - 240) = LODWORD(this.m_SkillBase.m_var[10].value);
                        //                             *(v1 - 236) = HIDWORD(this.m_SkillBase.m_var[10].value);
                        //                             *(v1 - 152) = LODWORD(this.m_SkillBase.m_var[6].value);
                        //                             *(v1 - 148) = HIDWORD(this.m_SkillBase.m_var[6].value);
                        //                             v32 = this.m_nEnhance;
                        //                             v33 = *(v1 - 152) / 10000.0;
                        //                             *(v1 - 40) = LODWORD(this.m_SkillBase.m_var[5].value);
                        //                             *(v1 - 36) = HIDWORD(this.m_SkillBase.m_var[5].value);
                        //                             *(v1 + 56) = *&v33;
                        // 
                        //                             *(v1 + 116) = (this.m_SkillBase.m_var[5] + this.m_nRequestedSkillLevel * this.m_SkillBase.m_var[6]) + (this.m_SkillBase.m_var[10] * this.m_nEnhance) * 12.0f;
                        //                             *(v1 + 112) = GameContent.g_nRegionSize;
                        //                             v36 = (objTarget.mv.x / GameContent.g_nRegionSize);
                        //                             *(v1 + 12) = v36;
                        //                             v37 = *(v1 + 12);
                        //                             if ( v36 < 0 )
                        //                                 v37 = v37 + 4294967300.0;
                        //                             *(v1 + 72) = v37;
                        //                             v38 = *(v1 + 116);
                        //                             *(v1 + 76) = *(v1 + 72) - *(v1 + 116);
                        //                             v39 = v1 + 76;
                        //                             if ( *(v1 - 124) <= *(v1 + 76) )
                        //                                 v39 = v1 - 124;
                        //                             *(v1 - 124) = *v39;
                        //                             v40 = (objTarget.mv.y / *(v1 + 112));
                        //                             *(v1 + 12) = v40;
                        //                             v41 = *(v1 + 12);
                        //                             if ( v40 < 0 )
                        //                                 v41 = v41 + 4294967300.0;
                        //                             *(v1 + 76) = v41;
                        //                             *(v1 - 16) = *(v1 + 76) - v38;
                        //                             v42 = v1 - 16;
                        //                             if ( *(v1 - 120) <= *(v1 - 16) )
                        //                                 v42 = v1 - 120;
                        //                             *(v1 - 120) = *v42;
                        //                             *(v1 - 44) = *(v1 + 72) + v38;
                        //                             v43 = v1 - 44;
                        //                             if ( *(v1 - 44) <= *(v1 - 108) )
                        //                                 v43 = v1 - 108;
                        //                             *(v1 - 108) = *v43;
                        //                             *(v1 - 32) = v38 + *(v1 + 76);
                        //                             v44 = v1 - 32;
                        //                             if ( *(v1 - 32) <= *(v1 - 104) )
                        //                                 v44 = v1 - 104;
                        //                             *(v1 - 104) = *v44;
                        //                         }
                        //                     }
                        rl = RappelzServer.Instance._LockArea((uint)(top_left.x / GameContent.g_nRegionSize),
                            (uint)(top_left.y / GameContent.g_nRegionSize),
                            (uint)(bottom_right.x / GameContent.g_nRegionSize),
                            (uint)(bottom_right.y / GameContent.g_nRegionSize));
                    }
                    else
                    {
                        if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.Unsummon
                            || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.UnsummonAndAddState)
                        {
                            // doing an unsummon

                            //                         v56 = this.m_Owner;
                            //                         v57 = v56->baseclass_0.baseclass_0.baseclass_0.vfptr;
                            //                         *(v1 + 48) = 0.0;
                            //                         v58 = v56[1].m_csEnemy.m_cs.DebugInfo;
                            //                         *(v1 + 44) = 0.0;
                            //                         *(v1 + 40) = 0.0;
                            //                         *(v1 + 52) = 0.0;
                            //                         *(v1 + 32) = 0.0;
                            //                         *(v1 + 28) = 0.0;
                            //                         *(v1 + 24) = 0.0;
                            //                         *(v1 + 36) = 0.0;
                            //                         if ( !(v57[1].onProcess)() )
                            //                             goto LABEL_170;
                            //                         if ( !v58 )
                            //                             goto LABEL_170;
                            //                         if ( !LOBYTE(v58[2].CriticalSection) )
                            //                             goto LABEL_170;
                            //                         v59 = v3->m_pOwner;
                            //                         *(v1 - 72) = *&v58[3].ProcessLocksList.Blink;
                            //                         *(v1 - 80) = v59->baseclass_0.baseclass_0.mv.baseclass_0.x;
                            //                         v60 = v1 - 72;
                            //                         if ( *(v1 - 80) <= *(v1 - 72) )
                            //                             v60 = v1 - 80;
                            //                         *(v1 + 40) = *v60;
                            //                         *(v1 - 88) = *&v58[3].EntryCount;
                            //                         *(v1 - 56) = v59->baseclass_0.baseclass_0.mv.baseclass_0.y;
                            //                         v61 = v1 - 88;
                            //                         if ( *(v1 - 56) <= *(v1 - 88) )
                            //                             v61 = v1 - 56;
                            //                         *(v1 + 44) = *v61;
                            //                         *(v1 + 8) = *&v58[3].ProcessLocksList.Blink;
                            //                         *(v1 - 84) = v59->baseclass_0.baseclass_0.mv.baseclass_0.x;
                            //                         v62 = v1 + 8;
                            //                         if ( *(v1 + 8) <= *(v1 - 84) )
                            //                             v62 = v1 - 84;
                            //                         *(v1 + 24) = *v62;
                            //                         *v1 = *&v58[3].EntryCount;
                            //                         *(v1 - 68) = v59->baseclass_0.baseclass_0.mv.baseclass_0.y;
                            //                         v63 = v1;
                            //                         if ( *v1 <= *(v1 - 68) )
                            //                             v63 = v1 - 68;
                            //                         v9 = v3->m_pSkillBase->effect_type == 605;
                            //                         *(v1 + 28) = *v63;
                            //                         v64 = v59[1].m_csEnemy.m_cs.LockCount;
                            //                         if ( v9 )
                            //                         {
                            //                             if ( v64 )
                            //                             {
                            //                                 if ( *(v64 + 68) )
                            //                                 {
                            //                                     *(v1 - 20) = *(v64 + 108);
                            //                                     v65 = v1 - 20;
                            //                                     if ( *(v1 + 40) <= *(v1 - 20) )
                            //                                         v65 = v1 + 40;
                            //                                     *(v1 + 40) = *v65;
                            //                                     *(v1 + 68) = *(v64 + 112);
                            //                                     v66 = v1 + 68;
                            //                                     if ( *(v1 + 44) <= *(v1 + 68) )
                            //                                         v66 = v1 + 44;
                            //                                     *(v1 + 44) = *v66;
                            //                                     *(v1 + 64) = *(v64 + 108);
                            //                                     v67 = v1 + 64;
                            //                                     if ( *(v1 + 64) <= *(v1 + 24) )
                            //                                         v67 = v1 + 24;
                            //                                     *(v1 + 24) = *v67;
                            //                                     *(v1 + 80) = *(v64 + 112);
                            //                                     v68 = v1 + 80;
                            //                                     if ( *(v1 + 80) <= *(v1 + 28) )
                            //                                         v68 = v1 + 28;
                            //                                     *(v1 + 28) = *v68;
                            //                                 }
                            //                             }
                            //                         }
                            //                         *(v1 + 112) = g_nRegionSize;
                            //                         v69 = *(v1 + 112);
                            //                         v70 = (*(v1 + 28) / *(v1 + 112));
                            //                         v71 = *(v1 + 44);
                            //                         *(v1 + 116) = (*(v1 + 24) / v69);
                            //                         v72 = (v71 / v69);
                            //                         v73 = *(v1 + 40) / v69;
                            //                         *(v1 + 104) = v72;
                            //                         v74 = *(v1 + 116);
                            //                         v75 = *(v1 + 104);
                            //                         v76 = ArcadiaServer::Instance();
                            //                         v77 = ArcadiaServer::_LockArea(v76, (v1 - 148), v73, v75, v74, v70, v4, 2672);
                            //                         ArcadiaAutoLock::set((v1 - 172), v77, v4, 2672);
                            //                         v78 = v3->m_pOwner[1].m_csEnemy.m_cs.DebugInfo;
                            //                         if ( !v78 || !LOBYTE(v78[2].CriticalSection) )
                            //                         {
                            //         LABEL_170:
                            //                             StructCreature::CancelSkill(v3->m_pOwner);
                            //                             return;
                            //                         }
                            /////////////////////////////////
                        }
                    }
                LABEL_93:

                    if (pTarget != null && !pTarget.bIsInWorld)
                    {
                        this.m_Owner.CancelSkill();
                        this.broadcastSkillMessage((int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                            (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize), this.m_Owner.m_layer, 0, 0, 0);
                        return;
                    }

                    bSuccess = true;

                    if (this.m_Status == SkillStatus.Fire)
                    {
                        /*******************************************************/

                        //                        v9 = !this.m_bMultiple;
                        cost_hp = 0;
                        cost_mp = 0;

                        /*******************************************************/
                        if (!this.m_bMultiple || this.m_nCurrentFire == 0)
                        {
                            // first fire
                            this.SetRemainCoolTime(this.GetSkillCoolTime());

                            if (this.m_SkillBase.cool_time_group_id != 0)
                            {
                                //                         v85 = v3->m_pOwner;
                                //                         *(v1 - 248) = v84->cool_time_group_id;
                                //                         *(v1 - 252) = &::::_mySkillFunctor::_vftable_;
                                //                         *(v1 - 244) = v83;
                                //                         this.m_Owner.EnumActiveSkill((v1 - 252));
                            }
                            player = null;
                            if (this.m_Owner.IsPlayer())
                            {
                                player = this.m_Owner as Player;
                                if (player != null)
                                    Messages.SendSkillMessage(player, player, this.m_SkillBase.uid);
                            }
                            else if (this.m_Owner.IsSummon())
                            {
                                pSummon = this.m_Owner as Summon;
                                if (pSummon != null)
                                    player = pSummon.m_master;
                                if (player != null)
                                    Messages.SendSkillMessage(player, pSummon, this.m_SkillBase.uid);
                            }
                        LABEL_107:

                            if ((this.m_SkillBase.effect_type == (int)SkillBase.EffectType.ToggleAura
                                || this.m_SkillBase.effect_type == (int)SkillBase.EffectType.ToggleDifferentialAura)
                                && this.m_Owner.IsActiveAura(this))
                            {
                                cost_mp = 0;
                            }
                            else
                            {
                                //                                 cost_mp = (this.m_Owner.GetManaCostRatio((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0)
                                //                                     * (this.m_Owner.m_nMaxMP * (this.m_SkillBase.cost_mp_per_skl_per * this.m_nRequestedSkillLevel + this.m_SkillBase.cost_mp_per) / 100.0f
                                //                                     + (this.m_SkillBase.cost_mp + this.m_nEnhance * this.m_SkillBase.cost_mp_per_enhance + this.m_nRequestedSkillLevel * this.m_SkillBase.cost_mp_per_skl)));
                                //                                 cost_mp = (cost_mp - cost_mp * 0.2f);
                            }
                            //                             v98 = v3->m_pSkillBase;
                            //                             v99 = v3->m_nRequestedSkillLevel;
                            //                             v100 = v98->cost_hp_per_skl_per;
                            //                             v101 = v3->m_pOwner->m_nMaxHP;
                            //                             *(v1 + 116) = v99;
                            //                             v102 = v100 * *(v1 + 116);
                            //                             *(v1 + 104) = v101;
                            //                             v103 = v99 * v98->cost_hp_per_skl;
                            //                             *(v1 + 116) = v102 + v98->cost_hp_per;
                            //                             v104 = *(v1 + 116) * *(v1 + 104);
                            //                             *(v1 + 116) = v98->cost_hp + v103;
                            //                             v105 = v3->m_nEnhance;
                            //                             v106 = v98->cost_exp_per_enhance;
                            //                             *(v1 + 96) = (v104 / 100.0 + *(v1 + 116));
                            //                             v107 = v98->cost_exp + v105 * v106;
                            //                             v9 = *(v1 + 96) == 0;
                            //                             v108 = *(v1 + 96) < 0;
                            //                             *(v1 + 80) = v98->cost_jp + v105 * v98->cost_jp_per_enhance;
                            //                             if ( !(v108 | v9) )
                            //                                 StructCreature::SetHP(v3->m_pOwner, v3->m_pOwner->m_nHP - *(v1 + 96));
                            //                             if ( *(v1 + 108) > 0 )
                            //                                 StructCreature::SetMP(v3->m_pOwner, v3->m_pOwner->m_nMP - *(v1 + 108));
                            //                             if ( v107 > 0 )
                            //                             {
                            //                                 v109 = v3->m_pOwner;
                            //                                 v110 = LODWORD(v109->m_nEXP);
                            //                                 *(v1 + 60) = HIDWORD(v109->m_nEXP);
                            //                                 StructCreature::SetEXP(v109, __PAIR__(*(v1 + 60), v110) - v107);
                            //                             }
                            //                             if ( *(v1 + 80) > 0 )
                            //                             {
                            //                                 v111 = (v3->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[6].onProcess)();
                            //                                 StructCreature::SetJP(v3->m_pOwner, v111 - *(v1 + 80));
                            //                             }
                            //                             v112 = v3->m_pOwner;
                            //                             v113 = v112->m_nMaxHavoc;
                            //                             if ( v113 )
                            //                             {
                            //                                 v114 = v3->m_nRequestedSkillLevel;
                            //                                 *(v1 + 116) = v112->m_nHavoc;
                            //                                 v115 = *(v1 + 116);
                            //                                 *(v1 + 116) = v113 * (v3->m_pSkillBase->cost_havoc + v114 * v3->m_pSkillBase->cost_havoc_per_skl);
                            //                                 StructCreature::SetHavoc(v112, (v115 - *(v1 + 116) / 100.0));
                            //                             }
                            //                             v116 = SkillBase::GetCostEnergy(v3->m_pSkillBase, (v1 - 308), v3->m_nRequestedSkillLevel)->value
                            //                                  / 10000.0;
                            //                             StructCreature::RemoveEnergy(v3->m_pOwner, v116);
                            //                             v117 = v3->m_pSkillBase;
                            //                             if ( v117->effect_type == 206 )
                            //                             {
                            //                                 v118 = LODWORD(v117->var[7].value);
                            //                                 v119 = LODWORD(v117->var[6].value);
                            //                                 *(v1 - 52) = LODWORD(v117->var[8].value);
                            //                                 v120 = HIDWORD(v117->var[8].value);
                            //                                 *(v1 - 216) = v118;
                            //                                 v121 = HIDWORD(v117->var[7].value);
                            //                                 v122 = HIDWORD(v117->var[6].value);
                            //                                 *(v1 - 48) = v120;
                            //                                 v123 = v3->m_nRequestedSkillLevel;
                            //                                 *(v1 + 60) = v122;
                            //                                 *(v1 - 212) = v121;
                            //                                 v124 = __PAIR__(*(v1 + 60), v119)
                            //                                      + c_fixed<10000>::operator_<int>((v1 - 216), (v1 - 268), v123)->value;
                            //                                 v125 = c_fixed<10000>::operator_<int>((v1 - 52), (v1 - 276), v3->m_nEnhance)->value + v124;
                            //                                 *(v1 - 52) = v125;
                            //                                 *(v1 - 48) = HIDWORD(v125);
                            //                                 v126 = v3->m_pOwner;
                            //                                 *(v1 + 104) = (*(v1 - 52) / 10000.0);
                            //                                 if ( !(v126->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
                            //                                   && !v3->m_pOwner[1].m_csEnemy.m_cs.DebugInfo )
                            //                                     goto LABEL_133;
                            //                                 v127 = v3->m_pOwner[1].m_csEnemy.m_cs.DebugInfo;
                            //                                 v128 = v127[6].ContentionCount;
                            //                                 v129 = __OFSUB__(*(v1 + 104), v128 - 1);
                            //                                 v108 = (*(v1 + 104) - (v128 - 1)) < 0;
                            //                                 *(v1 - 144) = v128 - 1;
                            //                                 v130 = v1 + 104;
                            //                                 if ( !(v108 ^ v129) )
                            //                                     v130 = v1 - 144;
                            //                             }
                            //                             else
                            //                             {
                            //                                 if ( v117->effect_type != 233
                            //                                   || (v131 = LODWORD(v117->var[10].value),
                            //                                       v132 = v117->var[9].value,
                            //                                       *(v1 - 64) = LODWORD(v117->var[11].value),
                            //                                       *(v1 - 60) = HIDWORD(v117->var[11].value),
                            //                                       v133 = v3->m_nRequestedSkillLevel,
                            //                                       *(v1 - 200) = v131,
                            //                                       *(v1 - 196) = HIDWORD(v117->var[10].value),
                            //                                       v134 = c_fixed<10000>::operator_<int>((v1 - 200), (v1 - 284), v133)->value + v132,
                            //                                       v135 = c_fixed<10000>::operator_<int>((v1 - 64), (v1 - 300), v3->m_nEnhance)->value + v134,
                            //                                       *(v1 - 64) = v135,
                            //                                       *(v1 - 60) = HIDWORD(v135),
                            //                                       v136 = v3->m_pOwner,
                            //                                       *(v1 + 116) = (*(v1 - 64) / 10000.0),
                            //                                       !(v136->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)())
                            //                                   && !v3->m_pOwner[1].m_csEnemy.m_cs.DebugInfo )
                            //                                     goto LABEL_133;
                            //                                 v127 = v3->m_pOwner[1].m_csEnemy.m_cs.DebugInfo;
                            //                                 v128 = v127[6].ContentionCount;
                            //                                 v129 = __OFSUB__(*(v1 + 116), v128 - 1);
                            //                                 v108 = (*(v1 + 116) - (v128 - 1)) < 0;
                            //                                 *(v1 + 100) = v128 - 1;
                            //                                 v130 = v1 + 116;
                            //                                 if ( !(v108 ^ v129) )
                            //                                     v130 = v1 + 100;
                            //                             }
                            //                             StructCreature::AddHP(v127, -*v130);
                            //                             BroadcastHPMPMsg(v127, v127[6].ContentionCount - v128, 0, 0);
                            //                                 LABEL_133:
                            //                                     //                     v137 = v3->m_pSkillBase;
                            //                                     //                     v138 = v137->cost_item;
                            //                                     //                     v139 = v137->cost_item_count + v3->m_nRequestedSkillLevel * v137->cost_item_count_per_skl;
                            //                                     //                     *(v1 - 28) = v139;
                            //                                     //                     *(v1 - 24) = HIDWORD(v139);
                            //                                     //                     if ( v138 )
                            //                                     //                     {
                            //                                     //                         v140 = 0;
                            //                                     //                         if ( (v3->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
                            //                                     //                             v140 = v3->m_pOwner;
                            //                                     //                         if ( (v3->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)() )
                            //                                     //                             v140 = v3->m_pOwner[1].baseclass_0.baseclass_0.prev_ry;
                            //                                     //                         if ( v140 )
                            //                                     //                         {
                            //                                     //                             if ( v138 == 100001 )
                            //                                     //                             {
                            //                                     //                                 *(v1 + 112) = StructPlayer::EraseBullet(v140, (v1 - 28));
                            //                                     //                             }
                            //                                     //                             else
                            //                                     //                             {
                            //                                     //                                 v141 = StructPlayer::FindItem(v140, v138);
                            //                                     //                                 if ( v141 && v141->m_Instance.nCount >= __PAIR__(*(v1 - 24), *(v1 - 28)) )
                            //                                     //                                     StructPlayer::EraseItem(v140, v141, (v1 - 28));
                            //                                     //                                 else
                            //                                     //                                     *(v1 + 112) = 0;
                            //                                     //                             }
                            //                                     //                         }
                            //                                     //                     }
                            //                                     goto LABEL_145;
                            //                                     ;
                            //                                 }

                            //                 v155 = 2684;
                            //                 v153 = v4;
                            //                 v54 = v3->m_pOwner;
                            //                 v55 = ArcadiaServer::Instance();
                            //                 v52 = ArcadiaServer::_LockObjectWithVisibleRange(v55, (v1 - 256), v54, v4, 2684);
                            //             }
                            //            ArcadiaAutoLock::set((v1 - 172), v52, v153, v155);
                            //             goto LABEL_93;
                            //                 }

                        }
                        /*******************************************************/



                        /*******************************************************/

//                         if (this.m_bMultiple && this.m_nCurrentFire != 0)
//                         {
//                         LABEL_145:
                        this.FireSkill(pTarget, bSuccess);
                        if (pTarget == null)
                            this.broadcastSkillMessage((int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                                (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize),
                                this.m_Owner.m_layer, cost_hp, cost_mp, 0);
                        else
                            this.broadcastSkillMessage((int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                                (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize),
                                (int)(pTarget.mv.x / GameContent.g_nRegionSize),
                                (int)(pTarget.mv.y / GameContent.g_nRegionSize),
                                this.m_Owner.m_layer, cost_hp, cost_mp, 0);
                        
                        if (!this.m_bMultiple || this.m_nCurrentFire == this.m_nTotalFire)
                        {
                            this.m_nFireTime += this.m_SkillBase.delay_common;
                            this.m_Status = SkillStatus.Complete;

                            for (i = 0; i < 2; ++i)
                            {
                                Item cw = this.m_Owner.GetWornItem((ItemBase.ItemWearType)i);

                                if (cw != null)
                                {
                                    if (cw.m_Instance.nCurrentEndurance > 0)
                                    {
                                        if (cw.GetUsingSocketCount() > 0)
                                        {
                                            cw.SetCurrentEndurance(cw.m_Instance.nCurrentEndurance - 1000);
                                            if (this.m_Owner.IsPlayer())
                                                Messages.SendItemMessage(this.m_Owner as Player, cw);
                                            if (cw.m_Instance.nCurrentEndurance == 0)
                                                this.m_Owner.m_StatusFlag |= Creature.StatusFlags.NeedToCalculateStat;
                                        }
                                    }
                                }
                            }
                        }
//                        }
                    }

                    if (this.m_Status == SkillStatus.Complete)
                    {
                        if (ct >= this.m_nFireTime)
                        {
                            if (pTarget != null)
                                this.broadcastSkillMessage(
                                    (int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                                    (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize),
                                    (int)(pTarget.mv.y / GameContent.g_nRegionSize),
                                    (int)(pTarget.mv.y / GameContent.g_nRegionSize),
                                    this.m_Owner.m_layer, 0, 0, 5);
                            else
                                this.broadcastSkillMessage(
                                    (int)(this.m_Owner.mv.x / GameContent.g_nRegionSize),
                                    (int)(this.m_Owner.mv.y / GameContent.g_nRegionSize),
                                    this.m_Owner.m_layer, 0, 0, 5);
                            this.m_Owner.OnCompleteSkill();
                            this.Init();
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
            	
            }
            finally
            {

            }



        }

        public bool ProcAura()
        {
            return false;
        }

        public static void SendSkillCastFailMessage(Player pPlayer, uint caster, uint target, ushort skill_id, byte skill_lv, ArPosition pos, int error_code)
        {
//             double v7; // st7@1
//             double v8; // st7@1
//             TS_SC_SKILL msg; // [sp+0h] [bp-34h]@1
// 
//             TS_SC_SKILL::TS_SC_SKILL(&msg);
//             msg.x = pos->x;
//             msg.type = 1;
//             v7 = pos->y;
//             msg.layer = 0;
//             msg.y = v7;
//             msg.hp_cost = 0;
//             v8 = pos->z;
//             msg.caster = caster;
//             msg.z = v8;
//             msg.skill_id = skill_id;
//             msg.skill_level = skill_lv;
//             msg.target = target;
//             msg.___u14.cast.nErrorCode = error_code;
//             msg.mp_cost = 0;
//             msg.caster_hp = 0;
//             msg.caster_mp = 0;
//             *&msg.___u14.cancel.dummy[0] = 0;
//             PendMessage(pObject, &msg.baseclass_0);
        }


        protected void Init()
        {
            this.m_targetPos.x = 0.0f;
            this.m_targetPos.y = 0.0f;
            this.m_nErrorCode = 0;
            this.m_Status = 0;
            this.m_nCastTime = 0;
            this.m_nCastingDelay = 0;
            this.m_nFireTime = 0;
            this.m_nRequestedSkillLevel = 0;
            this.m_hTarget = 0;
            this.m_targetLayer = 0;
            this.m_nCurrentFire = 0;
            this.m_nTotalFire = 0;
            this.m_targetPos.z = 0.0f;
            this.m_nTargetCount = 1;
            this.m_nFireCount = 1;
            this.m_targetPos.face = 0.0f;
//            std::vector<SkillResult_std::allocator<SkillResult>>::clear(&this->m_vResultList);

        }

        protected void bindSkillInfo(int skill_id)
        {
            this.m_SkillBase = GameContent.GetSkillBase(skill_id);
            short et = this.m_SkillBase.effect_type;
            if (et == 107
              || et == 202
              || et == 204
              || et == 206
              || et == 212
              || et == 151
              || et == 152
              || et == 108
              || et == 232
              || et == 233
              || et == 263
              || et == 30004
              || et == 30005
              || et == 30009
              || et == 30017
              || et == 30018)
                this.m_bMultiple = true;
        }

        protected void assembleMessage(PacketOut pak, int nType, int cost_hp, int cost_mp)
        {
            pak.WriteUInt16((ushort)this.m_SkillBase.uid);
            pak.WriteByte((byte) this.m_nRequestedSkillLevel);
            pak.WriteUInt32((uint)this.m_Owner.m_hHandle);
            pak.WriteUInt32((uint)this.m_hTarget);
            pak.WriteFloat(this.m_targetPos.x);
            pak.WriteFloat(this.m_targetPos.y);
            pak.WriteFloat(this.m_targetPos.z);
            pak.WriteByte((byte)this.m_targetLayer);
            pak.WriteByte((byte)nType);
            pak.WriteInt32(cost_hp);
            pak.WriteInt32(cost_mp);
            pak.WriteInt32((int)this.m_Owner.m_nHP);
            pak.WriteInt32((int)this.m_Owner.m_fMP);


            if (nType != 0)
            {
                if ( nType <= 0 )
                    return;
                if ( nType <= 2 || nType == 5)
                {
                    pak.WriteUInt32(this.m_nFireTime - this.m_nCastTime);
                    pak.WriteUInt16((ushort)this.m_nErrorCode);
                    pak.WriteByte(0);
                    pak.WriteByte(0);
                    pak.WriteByte(0);
                    return;
                }
                if ( nType != 4 )
                    return;
            }

            pak.WriteByte((byte)(this.m_bMultiple ? 1 : 0));
            pak.WriteFloat(this.m_fRange);
            pak.WriteByte((byte)this.m_nTargetCount);
            pak.WriteByte((byte)this.m_nFireCount);
            pak.WriteUInt16((ushort)this.m_vResultList.Count);

            if (this.m_vResultList.Count > 0)
            {
                foreach (SkillResult sr in this.m_vResultList)
                {
                    switch(sr.type)
                    {
                        case (int)SkillResult.ResultType.Damage: // 0
                        case (int)SkillResult.ResultType.MagicDamage: // 1
                            pak.WriteByte(sr.type);
                            pak.WriteUInt32(sr.hTarget);
                            pak.WriteInt32(sr.damage.target_hp);
                            pak.WriteByte(sr.damage.damage_type);
                            pak.WriteInt32(sr.damage.damage);
                            pak.WriteInt32(sr.damage.flag);
                            pak.WriteUInt16(sr.damage.elemental_damage[0]);
                            pak.WriteUInt16(sr.damage.elemental_damage[1]);
                            pak.WriteUInt16(sr.damage.elemental_damage[2]);
                            pak.WriteUInt16(sr.damage.elemental_damage[3]);
                            pak.WriteUInt16(sr.damage.elemental_damage[4]);
                            pak.WriteUInt16(sr.damage.elemental_damage[5]);
                            pak.WriteUInt16(sr.damage.elemental_damage[6]);
                            pak.Fill(0, 13);
                            break;

                        case (int)SkillResult.ResultType.DamageWithKnockBack: // 2
//                             v12 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
//                             memcpy(pResultData, v12, 0x2Du);
//                             pResultData += 45;
                            break;

                        case (int)SkillResult.ResultType.Result: // 10
                            pak.WriteByte(sr.type);
                            pak.WriteUInt32(sr.hTarget);
                            pak.WriteByte((byte)(sr.result.bResult ? 1 : 0));
                            pak.WriteInt32(sr.result.success_type);
                            pak.Fill(0, 35);
                            break;

                        case (int)SkillResult.ResultType.AddHP: // 20
                        case (int)SkillResult.ResultType.AddMP: // 21
                            pak.WriteByte(sr.addHPType.type);
                            pak.WriteUInt32(sr.addHPType.hTarget);
                            pak.WriteInt32(sr.addHPType.target_hp);
                            pak.WriteInt32(sr.addHPType.nIncHP);
                            pak.Fill(0, 32);
                            break;

                        case (int)SkillResult.ResultType.AddHPMPSP: // 22
                            break;

                        case (int)SkillResult.ResultType.Rebirth: // 23
                            break;

                        case (int)SkillResult.ResultType.Rush: // 30
                            break;
                    }
                    if (sr.type > 21)
                    {
                        if (sr.type == 30)
                        {
                            // rush
//                             v17 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
//                             memcpy(pResultData, v17, 0x13u);
//                             pResultData += 19;
                        }
                        else
                        {
//                             v18 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
//                             memcpy(pResultData, v18, 0x17u);
//                             pResultData += 23;
                        }
                    }
                    else
                    {
                        if (sr.type >= 20 )
                        {
                        }
                        else
                        {
                            if (sr.type >= 0 )
                            {
                                if (sr.type <= 1 )
                                {
//                                     v13 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
//                                     memcpy(pResultData, v13, 0x20u);
//                                     pResultData += 32;
                                }
                                else
                                {
                                    if (sr.type == 2 )
                                    {
                                    }
                                    else
                                    {
                                        if (sr.type == 10 )
                                        {
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

// Function       :   protected void StructSkill::sendSkillMessage(int)

        protected void broadcastSkillMessage(int rx1, int ry1, int rx2, int ry2, byte layer, int cost_hp, int cost_mp, int nType)
        {
            PacketOut sp = new PacketOut(ClientOutPackets.Skill);

            this.assembleMessage(sp, nType, cost_hp, cost_mp);
            RappelzServer.Instance.Broadcast((uint)rx1, (uint)ry1, (uint)rx2, (uint)ry2, layer, sp);

/*
            StructSkill *v9; // edi@1
            void *v10; // esi@2
            unsigned int v11; // eax@3
            ArcadiaServer *v12; // eax@4
            char szBuf[16384]; // [sp+0h] [bp-4004h]@1
            unsigned int v14; // [sp+4000h] [bp-4h]@1
            int v15; // [sp+4004h] [bp+0h]@1

            v14 = &v15 ^ __security_cookie;
            v9 = this;
            szBuf[0] = 0;
            memset(&szBuf[1], 0, 0x3FFFu);
            if ( 45 * std::vector<SkillResult_std::allocator<SkillResult>>::size(&v9->m_vResultList) + 51 >= 0x4000 )
            {
                v11 = std::vector<SkillResult_std::allocator<SkillResult>>::size(&v9->m_vResultList);
                v10 = operator new__(45 * v11 + 51);
            }
            else
            {
                v10 = szBuf;
            }
            this.assembleMessage(v10, nType, cost_hp, cost_mp);
            v12 = ArcadiaServer::Instance();
            ArcadiaServer::Broadcast(v12, rx1, ry1, rx2, ry2, layer, v10);
            if ( v10 != szBuf )
                operator delete__(v10);
*/
        }

        public void broadcastSkillMessage(int rx, int ry, byte layer, int cost_hp, int cost_mp, int nType)
        {
            PacketOut sp = new PacketOut(ClientOutPackets.Skill);

            this.assembleMessage(sp, nType, cost_hp, cost_mp);
            RappelzServer.Instance.Broadcast((uint)rx, (uint)ry, layer, sp);
        }

        public int m_nEnhance;                                              // 0x4
        public int m_nSkillUID;                                             // 0x8
        public int m_nSkillId;                                              // 0xC
        public int m_nSkillLevel;                                           // 0x10
        public int m_nSkillLevelAdd;                                        // 0x14
        public int m_nRequestedSkillLevel;                                  // 0x18
        public SkillBase m_SkillBase;                                       // 0x1C
        public bool m_bNeedUpdateToDB;                                      // 0x20
        public ArPosition m_targetPos = new ArPosition();                   // 0x24 
        public byte m_targetLayer;                                          // 0x34
        public uint m_hTarget;                                              // 0x38
        public uint m_nCastingDelay;                                        // 0x3C
        public uint m_nCastTime;                                            // 0x40
        public uint m_nFireTime;                                            // 0x44
        public uint m_nNextCoolTime;                                        // 0x48
        public uint m_nAuraMPDecTime;                                       // 0x4C
        public uint m_nAuraRefreshTime;                                     // 0x50
        public Creature m_Owner;                                            // 0x54
        public SkillStatus m_Status;                                        // 0x58
        public bool m_bMultiple;                                            // 0x5C
        public int m_nErrorCode;                                            // 0x60
        public float m_fRange;                                              // 0x64
        public int m_nCurrentFire;                                          // 0x68
        public int m_nTotalFire;                                            // 0x6C
        public int m_nTargetCount;                                          // 0x70
        public int m_nFireCount;                                            // 0x74
        public ArPosition m_RushPos = new ArPosition();                     // 0x78
        public float m_fRushFace;                                           // 0x88
        public int m_nRushDamage;                                           // 0x8C
        public List<SkillResult> m_vResultList = new List<SkillResult>();            // 0x90

        private void FireSkill(Creature pTarget, bool bIsSuccess)
        {
            FireSkillStateSkillFunctor fn;
// .text:004D89C7 myStateSkillFunctor= STATE_SKILL_FUNCTOR ptr  18h
            //List<RappelzPair<float, int>> HateMod = new List<RappelzPair<float, int>>(); // 32  20h
            RappelzPair<float, int> HateMod;
            float fHV;                                              // 52   34h
            Creature pDealTarget = null;                            // 52   34h
            uint t;                                                 // 60   3Ch
// .text:004D89C7 cit             = StructCreature::iterator ptr  40h
            List<Creature> vNeedStateList = new List<Creature>();   // 72   48h
            float fSC;                                              // 92   5Ch
            int nAddHate;                                           // 92   5Ch
// .text:004D89C7 mySkillFunctor  = REMOVE_GOOD_STATE_SKILL_FUNCTOR ptr  60h
// .text:004D89C7 it              = std::_Vector_iterator<SkillResult,std::allocator<SkillResult> > ptr  68h
// .text:004D89C7 pTarget         = dword ptr  120  78h
// .text:004D89C7 bIsSuccess      = byte ptr   124  7Ch


            t = this.m_nFireTime;
            this.m_vResultList.Clear();
            bool isProcessed = true;

            if ((this.m_Owner.m_StatusFlag & Creature.StatusFlags.Hiding) != 0)
                this.m_Owner.RemoveState(State.StateCode.Hide, 65535);
//             v8 = this.m_SkillBase.;
//             v9 = this.m_SkillBase.effect_type;
//             v10 = pTarget;

            switch (this.m_SkillBase.effect_type)
            {
                case (int)SkillBase.EffectType.RespawnMonsterNear:
                    this.RESPAWN_NEAR_MONSTER();
                    break;

                case (int)SkillBase.EffectType.SummonScroll:
                    this.SUMMON_SCROLL();
                    break;

                case (int)SkillBase.EffectType.MagicSingleDamage:
                case (int)SkillBase.EffectType.MagicSingleDamageAddRandomState:
                    this.SINGLE_MAGICAL_DAMAGE(pTarget);
                    break;

                case (int)SkillBase.EffectType.MagicMultipleDamage:
                case (int)SkillBase.EffectType.MagicMultipleDamageDealSummonHp:
                    this.MULTIPLE_MAGICAL_DAMAGE(pTarget);
                    break;

                case (int)SkillBase.EffectType.MagicDamageWithAbsorbHPMP:
                    this.SINGLE_MAGICAL_DAMAGE_WITH_ABSORB(pTarget);
                    break;

                case (int)SkillBase.EffectType.MagicSingleRegionDamage: // 261:
                case (int)SkillBase.EffectType.MagicSingleRegionDamageUsingCorpse: // 265:
                case (int)SkillBase.EffectType.MagicSingleRegionDamageAddRandomState: // 268:
                    this.MAGIC_SINGLE_REGION_DAMAGE(pTarget);
                    break;

                case (int)SkillBase.EffectType.AreaEffectMagicDamage: // 271:
                case (int)SkillBase.EffectType.AreaEffectMagicDamageAndHeal: // 272:
                case (int)SkillBase.EffectType.AreaEffectMagicDamageAndHealT2: // 273:
                    this.MAKE_AREA_EFFECT_PROP(pTarget, false);
                    break;

                case (int)SkillBase.EffectType.AddState:
                    fn = new FireSkillStateSkillFunctor();
                    fn.pvList = m_vResultList;
                    this.process_target(t, fn, pTarget);
                    if ((this.m_SkillBase.uid - 6014) <= 5)
                    {
                        if (pTarget != null && pTarget.IsPlayer())
                            (pTarget as Player).Save(false);
                    }
                    break;

                case (int)SkillBase.EffectType.AddStateByItemCost:
                    fn = new FireSkillStateSkillFunctor();
                    fn.pvList = m_vResultList;
                    this.process_target(t, fn, pTarget);
                    if ((this.m_SkillBase.uid - 6014) <= 5)
                    {
                        if (pTarget != null && pTarget.IsPlayer())
                            (pTarget as Player).Save(false);
                    }
                    break;

                case (int)SkillBase.EffectType.Summon:
                    if (this.m_Owner.IsPlayer())
                        this.Summon();
                    break;

                case (int)SkillBase.EffectType.Unsummon:
                    if (this.m_Owner.IsPlayer())
                        this.UnSummon();
                    break;

                case (int) SkillBase.EffectType.ActivateFieldProp:
                    this.ACTIVATE_FIELD_PROP();
                    break;

                default:
                    isProcessed = false;
                    break;
            }

//             if (this.m_SkillBase.effect_type <= 302 )
//             {
//                 if (this.m_SkillBase.effect_type == 302 )
//                 {
//                     this.ADD_REGION_STATE(pTarget);
//                     goto LABEL_214;
//                 }
//                 if (this.m_SkillBase.effect_type > 206 )
//                 {
//                     switch (this.m_SkillBase.effect_type)
//                     {
// 
// /*
//                             if (v9 == 9501)
//                             {
//                                 StructSkill::ACTIVATE_FIELD_PROP();
//                                 goto LABEL_214;
//                             }
// */
// 
//                         case 231:
//                         case 239:
//                             this.SINGLE_MAGICAL_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 240:
//                             goto $LN115;
//                         case 241:
//                             this.MULTIPLE_MAGICAL_DAMAGE_AT_ONCE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 234:
//                             this.SINGLE_MAGICAL_DAMAGE_OR_DEATH(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 266:
//                             this.ADD_HP_MP_BY_ABSORB_HP_MP(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 236:
//                             this.SINGLE_MAGICAL_TARGET_HP_PERCENT_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 237:
//                         case 238:
//                             StructSkill::SINGLE_MAGICAL_MANABURN(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 211:
//                             StructSkill::MAGIC_SINGLE_REGION_DAMAGE_OLD(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 267:
//                             StructSkill::MAGIC_SINGLE_REGION_DAMAGE_BY_SUMMON_DEAD(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 269:
//                             StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_AT_ONCE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 212:
//                             StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_OLD(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 214:
//                             StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_T2(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 213:
//                             StructSkill::MAGIC_SPECIAL_REGION_DAMAGE_OLD(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 262:
//                             StructSkill::MAGIC_SPECIAL_REGION_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 263:
//                             StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 264:
//                             StructSkill::MAGIC_SINGLE_REGION_PERCENT_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 221:
//                             StructSkill::MAGIC_ABSORB_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         case 301:
//                             goto $LN164;
//                         case 271:
//                         case 272:
//                         case 273:
//                             goto $LN136;
//                         default:
//                             goto LABEL_194;
//                     }
//                     goto LABEL_194;
//                 }
//                 if ( v9 != 206 )
//                 {
//                     if ( v9 <= 117 )
//                     {
//                         if ( v9 == 117 )
//                         {
//                             StructSkill::SINGLE_PHYSICAL_DAMAGE_WITH_SHIELD(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v9 <= 106 )
//                         {
//                             if ( v9 != 106 )
//                             {
//                                 v11 = v9 - 2;
//                                 if ( !v11 )
//                                 {
//                                     StructSkill::RESPAWN_NEAR_MONSTER(v5);
//                                     goto LABEL_214;
//                                 }
//                                 v12 = v11 - 99;
//                                 if ( v12 )
//                                 {
//                                     v13 = v12 - 1;
//                                     if ( !v13 )
//                                     {
//                                         StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T1(v5, *(v3 + 120));
//                                         goto LABEL_214;
//                                     }
//                                     v14 = v13 - 1;
//                                     if ( !v14 )
//                                     {
//                                         StructSkill::SINGLE_PHYSICAL_DAMAGE_T2(v5, *(v3 + 120));
//                                         goto LABEL_214;
//                                     }
//                                     v15 = v14 - 1;
//                                     if ( !v15 )
//                                     {
//                                         StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T2(v5, *(v3 + 120));
//                                         goto LABEL_214;
//                                     }
//                                     if ( v15 == 1 )
//                                     {
//                                         StructSkill::PHYSICAL_DIRECTIONAL_DAMAGE(v5, *(v3 + 120));
//                                         goto LABEL_214;
//                                     }
//                                     goto LABEL_194;
//                                 }
//         LABEL_21:
//                                 StructSkill::SINGLE_PHYSICAL_DAMAGE_T1(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//         LABEL_41:
//                             StructSkill::SINGLE_PHYSICAL_DAMAGE_T3(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v16 = v9 - 107;
//                         if ( !v16 )
//                         {
//                             StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T3(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v17 = v16 - 1;
//                         if ( !v17 )
//                         {
//                             StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T4(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v18 = v17 - 3;
//                         if ( v18 )
//                         {
//                             v19 = v18 - 1;
//                             if ( !v19 )
//                             {
//                                 StructSkill::PHYSICAL_MULTIPLE_REGION_DAMAGE_OLD(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             if ( v19 == 1 )
//                             {
//                                 StructSkill::PHYSICAL_SPECIAL_REGION_DAMAGE(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             goto LABEL_194;
//                         }
//                         goto LABEL_43;
//                     }
//                     if ( v9 <= 152 )
//                     {
//                         if ( v9 == 152 )
//                             goto LABEL_21;
//                         v20 = v9 - 121;
//                         if ( !v20 )
//                         {
//                             StructSkill::SINGLE_PHYSICAL_DAMAGE_ABSORB(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v21 = v20 - 1;
//                         if ( !v21 )
//                         {
//                             StructSkill::PHYSICAL_MULTIPLE_SPECIAL_REGION_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v22 = v21 - 3;
//                         if ( !v22 )
//                         {
//                             StructSkill::SINGLE_PHYSICAL_DAMAGE_T2_ADD_ENERGY(v5, *(v3 + 120));
//                             goto LABEL_43;
//                         }
//                         v23 = v22 - 6;
//                         if ( !v23 )
//                             goto LABEL_21;
//                         v24 = v23 - 1;
//                         if ( !v24 )
//                         {
//         LABEL_43:
//                             StructSkill::PHYSICAL_SINGLE_REGION_DAMAGE_OLD(v5, v10);
//                             goto LABEL_214;
//                         }
//                         if ( v24 == 19 )
//                             goto LABEL_41;
//                         goto LABEL_194;
//                     }
//                     v25 = v9 - 201;
//                     if ( !v25 )
//                     {
//                         StructSkill::SINGLE_MAGICAL_DAMAGE_T1(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     v26 = v25 - 1;
//                     if ( v26 )
//                     {
//                         v27 = v26 - 1;
//                         if ( !v27 )
//                         {
//                             StructSkill::SINGLE_MAGICAL_DAMAGE_T2(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v28 = v27 - 1;
//                         if ( !v28 )
//                         {
//                             StructSkill::MULTIPLE_MAGICAL_DAMAGE_T2(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v28 == 1 )
//                         {
//                             StructSkill::MULTIPLE_MAGICAL_DAMAGE_T3(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         goto LABEL_194;
//                     }
//                 }
//                 StructSkill::MULTIPLE_MAGICAL_DAMAGE_T1(v5, *(v3 + 120));
//                 goto LABEL_214;
//             }
//             if ( v9 > 902 )
//             {
//                 if ( v9 > 30010 )
//                 {
//                     if ( v9 > 30017 )
//                     {
//                         v39 = v9 - 30018;
//                         if ( !v39 )
//                         {
//                             StructSkill::PHYSICAL_REALTIME_MULTIPLE_REGION_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v40 = v39 - 1;
//                         if ( !v40 )
//                         {
//         $LN115:
//                             StructSkill::SINGLE_DAMAGE_BY_CONSUMING_TARGETS_STATE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         v41 = v40 - 11;
//                         if ( v41 )
//                         {
//                             v42 = v41 - 471;
//                             if ( !v42 )
//                             {
//                                 StructSkill::SKILL_RESURRECTION_WITH_RECOVER(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             if ( v42 != 100 )
//                                 goto LABEL_194;
//                             v46 = v5->m_pOwner;
//                             *(v3 + 72) = &REMOVE_STATE_GROUP_SKILL_FUNCTOR::_vftable_;
//                             *(v3 + 80) = v46;
//                             goto LABEL_117;
//                         }
//                     }
//                     else
//                     {
//                         if ( v9 == 30017 )
//                             goto LABEL_173;
//                         if ( v9 != 30011 )
//                         {
//                             if ( v9 != 30012 )
//                             {
//                                 if ( v9 == 30013 )
//                                 {
//                                     StructSkill::PHYSICAL_SINGLE_SPECIAL_REGION_DAMAGE(v5, *(v3 + 120));
//                                     goto LABEL_214;
//                                 }
//                                 if ( v9 <= 30013 )
//                                     goto LABEL_194;
//                                 if ( v9 > 30015 )
//                                 {
//                                     if ( v9 == 30016 )
//                                     {
//                                         StructSkill::PHYSICAL_MULTIPLE_DAMAGE(v5, *(v3 + 120));
//                                         goto LABEL_214;
//                                     }
//                                     goto LABEL_194;
//                                 }
//                             }
//                             StructSkill::PHYSICAL_MULTIPLE_REGION_DAMAGE(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                     }
//                 }
//                 else
//                 {
//                     if ( v9 == 30010 )
//                     {
//                         StructSkill::PHYSICAL_MULTIPLE_DAMAGE_TRIPLE_ATTACK(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     if ( v9 <= 30001 )
//                     {
//                         if ( v9 != 30001 )
//                         {
//                             v34 = v9 - 903;
//                             if ( !v34 )
//                             {
//                                 StructSkill::REGION_REMOVE_HATE(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             v35 = v34 - 98;
//                             if ( !v35 )
//                             {
//                                 StructSkill::CORPSE_EXPLOSION(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             v36 = v35 - 8000;
//                             if ( !v36 )
//                             {
//                                 StructSkill::CREATE_ITEM(v5, v10, *(v3 + 124));
//                                 goto LABEL_214;
//                             }
//                             v37 = v36 - 500;
//                             v38 = v37 - 1;
//                             if ( !v38 )
//                             {
//                                 StructSkill::REGION_HEAL_BY_FIELD_PROP(v5);
//                                 goto LABEL_214;
//                             }
//                             if ( v38 == 1 )
//                             {
//                                 StructSkill::MAKE_AREA_EFFECT_PROP_BY_FIELD_PROP(v5, 0);
//                                 goto LABEL_214;
//                             }
//                             goto LABEL_194;
//                         }
//                         goto LABEL_174;
//                     }
//                     if ( v9 == 30002 )
//                     {
//                         StructSkill::PHYSICAL_SINGLE_DAMAGE_ABSORB(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     if ( v9 == 30003 )
//                     {
//                         StructSkill::PHYSICAL_SINGLE_DAMAGE_ADD_ENERGY(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     if ( v9 <= 30003 )
//                         goto LABEL_194;
//                     if ( v9 <= 30006 )
//                     {
//         LABEL_174:
//                         StructSkill::PHYSICAL_SINGLE_DAMAGE(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     if ( v9 > 30008 )
//                     {
//                         if ( v9 != 30009 )
//                             goto LABEL_194;
//         LABEL_173:
//                         StructSkill::PHYSICAL_REALTIME_MULTIPLE_DAMAGE(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                 }
//                 StructSkill::PHYSICAL_SINGLE_REGION_DAMAGE(v5, *(v3 + 120));
//                 goto LABEL_214;
//             }
//             if ( v9 == 902 )
//             {
//                 StructSkill::REMOVE_HATE(v5, *(v3 + 120));
//                 goto LABEL_214;
//             }
//             if ( v9 > 508 )
//             {
//                 if ( v9 > 601 )
//                 {
//                     if ( v9 == 605 )
//                     {
//                         if ( (v5->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
//                             StructSkill::UnSummonAndAddState(v5);
//                         goto LABEL_214;
//                     }
//                     if ( v9 > 700 )
//                     {
//                         if ( v9 <= 702 )
//                         {
//                             StructSkill::TOGGLE_AURA(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v9 == 900 )
//                         {
//                             StructSkill::TAUNT(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v9 == 901 )
//                         {
//                             StructSkill::REGION_TAUNT(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                     }
//                     goto LABEL_194;
//                 }
//                 if ( v9 == 509 )
//                 {
//                     *(v3 + 72) = &HEALING_SKILL_FUNCTOR::_vftable_;
//                 }
//                 else
//                 {
//                     if ( v9 != 510 )
//                     {
//                         if ( v9 == 511 )
//                         {
//                             StructSkill::CORPSE_ABSORB(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v9 <= 511 )
//                             goto LABEL_194;
//                         if ( v9 > 513 )
//                         {
//                             if ( v9 == 521 )
//                             {
//                                 StructSkill::SKILL_ADD_REGION_HP(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             if ( v9 == 522 )
//                             {
//                                 StructSkill::SKILL_ADD_REGION_MP(v5, *(v3 + 120));
//                                 goto LABEL_214;
//                             }
//                             goto LABEL_194;
//                         }
//         LABEL_111:
//                         StructSkill::SKILL_ADD_HP_MP(v5, *(v3 + 120));
//                         goto LABEL_214;
//                     }
//                     *(v3 + 72) = &RECOVERY_MP_SKILL_FUNCTOR::_vftable_;
//                 }
//                 *(v3 + 84) = 1;
//                 goto LABEL_116;
//             }
//             if ( v9 == 508 )
//             {
//                 StructSkill::SKILL_ADD_REGION_HP_MP(v5, *(v3 + 120));
//                 goto LABEL_214;
//             }
//             if ( v9 > 401 )
//             {
//                 if ( v9 == 402 )
//                 {
//                     *(v3 + 96) = &REMOVE_GOOD_STATE_SKILL_FUNCTOR::_vftable_;
//                     goto LABEL_103;
//                 }
//                 if ( v9 == 501 )
//                 {
//                     *(v3 + 72) = &HEALING_SKILL_FUNCTOR::_vftable_;
//                 }
//                 else
//                 {
//                     if ( v9 != 502 )
//                     {
//                         if ( v9 == 504 )
//                         {
//                             StructSkill::SKILL_RESURRECTION(v5, *(v3 + 120));
//                             goto LABEL_214;
//                         }
//                         if ( v9 <= 504 || v9 > 507 )
//                             goto LABEL_194;
//                         goto LABEL_111;
//                     }
//                     *(v3 + 72) = &RECOVERY_MP_SKILL_FUNCTOR::_vftable_;
//                 }
//                 *(v3 + 84) = 0;
//         LABEL_116:
//                 *(v3 + 80) = 0;
//         LABEL_117:
//                 *(v3 + 76) = v6;
//                 v33 = v3 + 72;
//                 goto LABEL_104;
//             }
//             if ( v9 == 401 )
//             {
//                 *(v3 + 96) = &REMOVE_BAD_STATE_SKILL_FUNCTOR::_vftable_;
//         LABEL_103:
//                 *(v3 + 100) = v6;
//                 v33 = v3 + 96;
//         LABEL_104:
//                 StructSkill::process_target(v5, *(v3 + 60), v33, v10);
//                 goto LABEL_214;
//             }
//             if ( v9 <= 307 )
//             {
//                 if ( v9 == 307 )
//                 {
//         $LN164:
//                     v31 = *(v3 + 120);
//                     v32 = *(v3 + 60);
//                     *(v3 + 96) = &STATE_SKILL_FUNCTOR::_vftable_;
//                     *(v3 + 100) = v6;
//                     StructSkill::process_target(v5, v32, (v3 + 96), v31);
//                     if ( (v5->m_pSkillBase->uid - 6014) <= 5 )
//                     {
//                         if ( v10 )
//                         {
//                             if ( (v10->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(v10) )
//                                 StructPlayer::Save(v10, 0);
//                         }
//                     }
//                     goto LABEL_214;
//                 }
//                 v29 = v9 - 304;
//                 if ( !v29 )
//                 {
//                     StructSkill::CASTING_CANCEL_WITH_ADD_STATE(v5, *(v3 + 120));
//                     goto LABEL_214;
//                 }
//                 v30 = v29 - 1;
//                 if ( !v30 )
//                 {
//                     StructSkill::ADD_STATE_BY_SELF_COST(v5, *(v3 + 120));
//                     goto LABEL_214;
//                 }
//                 if ( v30 == 1 )
//                 {
//                     StructSkill::ADD_REGION_STATE_BY_SELF_COST(v5, *(v3 + 120));
//                     goto LABEL_214;
//                 }
//                 goto LABEL_194;
//             }
//             if ( v9 >= 352 )
//             {
//                 if ( v9 <= 353 )
//                 {
//         $LN136:
//                     v123 = 0;
//                 }
//                 else
//                 {
//                     if ( (v9 - 381) > 3 )
//                         goto LABEL_194;
//                     v123 = 1;
//                 }
//                 StructSkill::MAKE_AREA_EFFECT_PROP(v5, v10, v123);
//                 goto LABEL_214;
//             }
//         LABEL_194:
            if(!isProcessed)
            {
                switch(this.m_SkillBase.uid)
                {
                    case (int) SkillBase.SkillId.CreatureTaming:
                        this.CREATURE_TAMING(pTarget);
                        break;

                    case (int)SkillBase.SkillId.Return:
                    case (int)SkillBase.SkillId.TownPortal:
                        this.TOWN_PORTAL();
                        break;

                    default:
                        Globals.Log.Error("Unknown Skill - ID:{0}({1}) effect_type:{2}", GameContent.GetString(this.m_SkillBase.name_id), this.m_SkillBase.uid, this.m_SkillBase.effect_type);
                        break;
                        
                }
            }
//             v43 = v8->uid;
//             if ( v8->uid > 6020 )
//             {
//                 v44 = v43 - 6021;
//                 if ( v44 )
//                 {
//                     v45 = v44 - 886;
//                     if ( v45 )
//                     {
//                         if ( v45 == 1 )
//                             StructSkill::PET_TAMING(v5, *(v3 + 120));
//                     }
//                     else
//                     {
//                         StructSkill::SHOVELING(v5);
//                     }
//                 }
//                 else
//                 {
//                     StructSkill::RETURN_BACK_FEATHER(v5);
//                 }
//             }
//             else
//             {
//                 if ( v8->uid == 6020 )
//                 {
//                     StructSkill::RETURN_FEATHER(v5);
//                     goto LABEL_214;
//                 }
//                 if ( v43 == 2631 )
//                 {
//                     StructSkill::ADD_ENERGY(v5);
//                     goto LABEL_214;
//                 }
//                 if ( v43 == 3802 )
//                     goto LABEL_295;
//                 if ( v43 == 4003 )
//                 {
//                     StructSkill::CREATURE_TAMING(v5, *(v3 + 120));
//                     goto LABEL_214;
//                 }
//                 if ( v43 == 6007 )
//         LABEL_295:
//                     StructSkill::TOWN_PORTAL(v5);
//             }
        LABEL_214:
//             v47 = 0;
//             *(v3 + 76) = 0;
//             *(v3 + 80) = 0;
//             *(v3 + 84) = 0;
//             v48 = *(v6 + 4);

            foreach (SkillResult sr in this.m_vResultList)
            {
                if (sr.type == 0
                  || sr.type == 1
                  || sr.type == 2
                  || sr.type == 20
                  || sr.type == 21
                  || sr.type == 22
                  || sr.type == 10)
                {
                    pDealTarget = Creature.get(sr.hTarget) as Creature;
                    if (pDealTarget != null)
                    {
                        if (pDealTarget.m_nHP != 0)
                        {
                            if (this.m_SkillBase.effect_type != (short) SkillBase.EffectType.AddState
                                && this.m_SkillBase.effect_type != (short) SkillBase.EffectType.AddRegionState
                                && this.m_SkillBase.effect_type != (short)SkillBase.EffectType.AddStateByItemCost
                                && this.m_SkillBase.effect_type != (short) SkillBase.EffectType.PhysicalSingleDamageWithShield
                                && this.m_SkillBase.effect_type != (short) SkillBase.EffectType.AddStateBySelfCost
                                && this.m_SkillBase.effect_type != (short) SkillBase.EffectType.AddRegionStateBySelfCost
                                && this.m_SkillBase.effect_type != (short) SkillBase.EffectType.RemoveStateGroup
                                && this.m_SkillBase.state_id != 0
                                && sr.damage != null)
                            {
                                if ((sr.damage.flag ^ 2) != 0)
                                    vNeedStateList.Add(pDealTarget);
//                                 if (sr.type *(&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v3 + 104))->end.face
//                                      + 2) ^ 2 )
//                                     vNeedStateList.Add(pDealTarget);
                            }
                            int nDamage = 0;
                            if (!this.m_Owner.IsMonster())
                            {
                                if (this.m_SkillBase.effect_type != (short) SkillBase.EffectType.RemoveHate)
                                {
                                    if (this.m_SkillBase.effect_type != (short) SkillBase.EffectType.RegionRemoveHate)
                                    {
                                        nDamage = 0;
                                        if (sr.type != (byte)SkillResult.ResultType.Damage 
                                            && sr.type != (byte)SkillResult.ResultType.MagicDamage 
                                            && sr.type != (byte)SkillResult.ResultType.DamageWithKnockBack)
                                        {
                                            if (sr.type == (byte)SkillResult.ResultType.AddHP 
                                                || sr.type == (byte)SkillResult.ResultType.AddMP)
                                            {
//                                                 nDamage = sr.*(&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v3 + 104))->end.z
//                                                       + 1);
                                            }
                                            else if (sr.type == (byte)SkillResult.ResultType.AddHPMPSP)
                                            {
//                                                 v54 = *(&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v3 + 104))->end.z
//                                                       + 1);
//                                                 v55 = *(&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v3 + 104))->end.face
//                                                       + 1)
//                                                     + v54;
//                                                 nDamage = *(&std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v3 + 104))->end_time
//                                                       + 1)
//                                                     + v55;
                                            }
                                        }
                                        else
                                        {
                                            nDamage = sr.damage.damage;
                                        }

                                        float hm = (this.m_Owner.GetMagicalHateMod((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0) 
                                            * (this.m_SkillBase.GetHatePoint(this.m_nRequestedSkillLevel, nDamage, this.m_nEnhance) * this.m_Owner.m_fHateRatio));
                                        HateMod = this.m_Owner.GetHateMod(this.m_SkillBase.is_spell_act != 0 ? 2 : 1, this.m_SkillBase.is_harmful != 0);

                                        nDamage = (int)((hm + HateMod.Second) * HateMod.First);
                                        if (nDamage == 0)
                                            nDamage = 1;

                                        if (pDealTarget.IsMonster())
                                        {
                                            (pDealTarget as Monster).AddHate(this.m_Owner.m_hHandle, nDamage, true, true);
                                        }
                                        else
                                        {
                                            if (pDealTarget.IsNPC())
                                            {
                                                (pDealTarget as NPC).SetAttacker(this.m_Owner);
                                            }
                                            else
                                            {
                                                if (!this.m_Owner.IsEnemy(pDealTarget,false))
                                                {
                                                    pDealTarget.AddHateToEnemyList(this.m_Owner.m_hHandle, nDamage);
                                                }
                                            }
                                        }
                                        float fval1 = nDamage * 0.02f;
                                        if (nDamage <= 0 )
                                        {
                                            if (this.m_SkillBase.is_spell_act != 0)
                                                fval1 = nDamage * 0.25f;
                                            else
                                                fval1 = nDamage * 0.65f;
                                        }
                                        float fval2 = 1.0f;
                                        uint sct = this.GetSkillCoolTime();
                                        if (sct > 1000)
                                        {
                                            if (sct > 3000)
                                            {
                                                if (sct > 6000)
                                                {
                                                    if (sct > 15000)
                                                        fval2 = 2.0f;
                                                    else
                                                        fval2 = 1.7f;
                                                }
                                                else
                                                {
                                                    fval2 = 1.4f;
                                                }
                                            }
                                            else
                                            {
                                                fval2 = 1.2f;
                                            }
                                        }
                                        this.m_Owner.SetHavoc(this.m_Owner.m_nHavoc + (int)(fval2 * fval1));
                                    }
                                }
                            }
                        }

                    }
                }
                if (sr.type == 0
                  || sr.type == 1
                  || sr.type == 2)
                {
                    if ((sr.damage.flag & 1) != 0)
                        this.m_Owner.ProcessAddHPMPOnCritical();
                }
            }

//             v77 = *(v3 + 76);
//             *(v3 + 24) = &STATE_SKILL_FUNCTOR::_vftable_;
//             *(v3 + 28) = v6;
            if(vNeedStateList.Count > 0)
            {
                fn = new FireSkillStateSkillFunctor();
                fn.pvList = m_vResultList;

                foreach (Creature cr in vNeedStateList)
                {
                    this.process_target(t, fn, cr);
                }

            }

            this.m_Owner.RemoveExhaustiveSkillStateMod(this.m_SkillBase.is_spell_act == 0,
                this.m_SkillBase.is_harmful != 0,
                this.m_SkillBase.elemental,
                this.m_nCastingDelay);

            Player player = null;
            if (this.m_Owner.IsMonster())
            {
                Monster mob = this.m_Owner as Monster;

                if (mob.m_pContentInfo.monster_type >= 31)
                {
                    if (bIsSuccess)
                    {
                        if (pTarget == null)
                        {
                            ServerLog.Log((ushort)0xA91,0,0,0,0,0,mob.GetMonsterId(),(long)mob.mv.x,(long)mob.mv.y,mob.m_layer,this.m_SkillBase.uid,
                                this.m_nRequestedSkillLevel,"","","",mob.GetName());
                            return;

                        }
                        if (pTarget.IsPlayer())
                        {
                            player = pTarget as Player;
                        }
                        else
                        {
                            if (pTarget.IsSummon())
                                player = (pTarget as Summon).m_master;
                        }
                        if (player != null)
                        {
                            ServerLog.Log((ushort)0xA91,player.GetAccountID(),player.GetSID(),(long)pTarget.mv.x,(long)pTarget.mv.y,pTarget.m_layer,
                                mob.GetMonsterId(), (long)mob.mv.x, (long)mob.mv.y,mob.m_layer,this.m_SkillBase.uid,this.m_nRequestedSkillLevel,
                                player.GetAccountName(),player.GetName(),pTarget.GetName(),mob.GetName());
                            return;
                        }
                        ServerLog.Log((ushort)0xA91,0,0,(long)pTarget.mv.x,(long)pTarget.mv.y,pTarget.m_layer,mob.GetMonsterId(),
                            (long)mob.mv.x,(long)mob.mv.y,mob.m_layer,this.m_SkillBase.uid,this.m_nRequestedSkillLevel,"","",pTarget.GetName(),mob.GetName());
                        return;
                    }
                }
            }
        }

        protected void process_target(uint t, SkillTargetFunctor fn, Creature pTarget)
        {
// .text:004C4967 pos             = ArPosition ptr -90h
// .text:004C4967 var_80          = ArPosition ptr -80h
// .text:004C4967 var_70          = dword ptr -70h
// .text:004C4967 var_5C          = dword ptr -5Ch
// .text:004C4967 fo              = StructSkill::process_target::__l23::myPartyFunctor ptr -48h
// .text:004C4967 _fo             = GuildManager::GuildFunctor ptr -34h
// .text:004C4967 this            = StructSkill::process_target::__l45::myPartyFunctor ptr -20h
// .text:004C4967 pSummon         = dword ptr -0Ch
// .text:004C4967 var_4           = dword ptr -4
// .text:004C4967 t               = dword ptr  8
// .text:004C4967 functor         = dword ptr  0Ch
// .text:004C4967 pTargetPlayer   = dword ptr  10h
// 
// Data           :   enregistered ecx, Object Ptr, Type: struct StructSkill * const, this
// Data           :   ebp Relative, [00000008], Param, Type: unsigned long, t
// Data           :   ebp Relative, [0000000C], Param, Type: struct SKILL_TARGET_FUNCTOR &, functor
// Data           :   ebp Relative, [00000010], Param, Type: struct StructCreature *, pTarget
// Typedef        :   StructSkill::process_target::__l23::myPartyFunctor, Type: struct StructSkill::process_target::__l23::myPartyFunctor
// Data           :   ebp Relative, [FFFFFFB8], Local, Type: struct StructSkill::process_target::__l23::myPartyFunctor, fo
// Typedef        :   StructSkill::process_target::__l34::myGuildFunctor, Type: struct StructSkill::process_target::__l34::myGuildFunctor
// Data           :   ebp Relative, [FFFFFFCC], Local, Type: struct StructSkill::process_target::__l34::myGuildFunctor, fo
// Typedef        :   StructSkill::process_target::__l45::myPartyFunctor, Type: struct StructSkill::process_target::__l45::myPartyFunctor
// Data           :   ebp Relative, [FFFFFFE0], Local, Type: struct StructSkill::process_target::__l45::myPartyFunctor, fo
// Data           :   ebp Relative, [FFFFFF70], Local, Type: struct ArPosition, pos
// Data           :   ebp Relative, [FFFFFFF4], Local, Type: struct StructSummon *, pSummon
// Typedef        :   StructSkill::process_target::__l69::myPartyFunctor, Type: struct StructSkill::process_target::__l69::myPartyFunctor
// Data           :   ebp Relative, [FFFFFFA4], Local, Type: struct StructSkill::process_target::__l69::myPartyFunctor, fo
// Data           :   ebp Relative, [FFFFFF80], Local, Type: struct ArPosition, pos
// Data           :   ebp Relative, [00000010], Local, Type: struct StructPlayer *, pTargetPlayer
// Typedef        :   StructSkill::process_target::__l106::myPartyFunctor, Type: struct StructSkill::process_target::__l106::myPartyFunctor
// Data           :   ebp Relative, [FFFFFF90], Local, Type: struct StructSkill::process_target::__l106::myPartyFunctor, fo

//             v4 = this;
//             v5 = this.m_SkillBase;
//             v6 = this.m_SkillBase.target;

            switch(this.m_SkillBase.target)
            {
                case 1:
                case 6:
                    if (this.m_SkillBase.target == 6 && pTarget.IsSameObject(this.m_Owner))
                        return;
                    if (this.m_SkillBase.is_need_target != 0)
                    {
                        if (pTarget == null)
                            return;
                        fn.onCreature(this, t, this.m_Owner, pTarget);
                    }
                    else
                    {
                        fn.onCreature(this, t, this.m_Owner, this.m_Owner);
                    }
                    return;

                case 2:
                case 3:
                case 4:
                    if (pTarget == null)
                        return;
                    fn.onCreature(this, t, this.m_Owner, pTarget);
                    return;

            }

/*
            if (this.m_SkillBase.target > 31 )
            {
                v35 = this.m_SkillBase.target - 32;
                if (this.m_SkillBase.target == 32)
                {
                    if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
                        return;
                    ::::myPartyFunctor::myPartyFunctor(&v63, v4, t, v4->m_pOwner, functor);
                    v27 = *(v52 + 4244);
                    if ( !v27 )
                    {
                        (**v52)(v52);
                        v20 = v63;
                        v21 = &v63;
                        goto LABEL_109;
                    }
                    v28 = &v63;
                    goto LABEL_111;
                }
                v36 = v35 - 13;
                if ( v36 )
                {
                    v37 = v36 - 6;
                    if ( !v37 )
                    {
                        if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
                          && !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)()
                          || !(pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget)
                          && !pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle(pTarget) )
                            return;
                        if ( (v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
                        {
                            v41 = v4->m_pOwner;
                        }
                        else
                        {
                            if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)() )
                                return;
                            v41 = v4->m_pOwner[1].baseclass_0.baseclass_0.prev_ry;
                        }
                        if ( !v41 )
                            return;
                        v42 = (pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget);
                        v43 = pTarget;
                        if ( !v42 )
                        {
                            if ( !pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle(pTarget) )
                                return;
                            v43 = pTarget[1].baseclass_0.baseclass_0.prev_ry;
                        }
                        if ( !v43
                          || v41 != v43
                          && (v44 = *(&v41[1].baseclass_0.m_nRefCount + 1)) != 0
                          && v44 != *(&v43[1].baseclass_0.m_nRefCount + 1) )
                            return;
                        ::::myPartyFunctor::myPartyFunctor(&v62, v4, t, v4->m_pOwner, functor);
                        v27 = *(&v41[1].baseclass_0.m_nRefCount + 1);
                        if ( !v27 )
                        {
                            v41->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v41);
                            v20 = v62;
                            v21 = &v62;
                            goto LABEL_109;
                        }
                        v28 = &v62;
                        goto LABEL_111;
                    }
                    v38 = v37 - 50;
                    if ( !v38 )
                    {
                        if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)()
                          || (v40 = v4->m_pOwner[1].baseclass_0.baseclass_0.prev_ry) == 0
                          || !*(v40 + 68) )
                            return;
                        v59 = v4->m_pOwner[1].baseclass_0.baseclass_0.prev_ry;
                        v56 = v4->m_pOwner;
        LABEL_47:
                        (functor->vfptr->onCreature)(v4, t, v56, v59);
                        return;
                    }
                    if ( v38 != 1
                      || !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle)()
                      || !v4->m_pOwner->baseclass_0.baseclass_0.bIsInWorld
                      || (functor->vfptr->onCreature(functor, v4, t, v4->m_pOwner, v4->m_pOwner),
                          (v39 = v4->m_pOwner[1].baseclass_0.baseclass_0.prev_ry) == 0)
                      || !*(v39 + 68)
                      || ArPosition::GetDistance((v39 + 108), &v4->m_pOwner->baseclass_0.baseclass_0.mv.baseclass_0) > 525.0 )
                        return;
                    v29 = functor->vfptr;
                    v58 = v39;
                    v55 = v4->m_pOwner;
        LABEL_40:
                    (v29->onCreature)(v4, t, v55, v58);
                    return;
                }
                v45 = pTarget;
                if ( !(pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget) )
                {
                    if ( !pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle(pTarget)
                      || (v45 = pTarget[1].baseclass_0.baseclass_0.prev_ry) == 0 )
                        return;
                }
                pTargetPlayer = v45;
                if ( !v45 )
                    return;
                if ( !v45->baseclass_0.baseclass_0.bIsInWorld )
                    return;
                (functor->vfptr->onCreature)(v4, t, v4->m_pOwner, v45);
                v46 = &v4->m_pOwner->baseclass_0.baseclass_0.mv;
                LODWORD(v61.x) = *v46;
                v46 += 4;
                LODWORD(v61.y) = *v46;
                v46 += 4;
                LODWORD(v61.z) = *v46;
                LODWORD(v61.face) = *(v46 + 4);
                v47 = pTargetPlayer[1].m_csEnemy.m_cs.DebugInfo;
                if ( v47 )
                {
                    if ( LOBYTE(v47[2].CriticalSection) )
                    {
                        if ( v47[6].ContentionCount )
                        {
                            LODWORD(v69) = 12 * v4->m_pSkillBase->valid_range;
                            v69 = SLODWORD(v69);
                            v68 = v69;
                            v48 = ArPosition::GetDistance(&v61, &v47[3].ProcessLocksList.Blink);
                            if ( v48 <= v68 )
                                (functor->vfptr->onCreature)(v4, t, v4->m_pOwner, v47);
                        }
                    }
                }
                v49 = pTargetPlayer;
                v50 = pTargetPlayer[1].m_csEnemy.m_cs.LockCount;
                if ( !v50
                  || !*(v50 + 68)
                  || !*(v50 + 212)
                  || (pTargetPlayera = (12 * v4->m_pSkillBase->valid_range),
                      v68 = pTargetPlayera,
                      v51 = ArPosition::GetDistance(&v61, (v50 + 108)),
                      v51 > v68) )
                    return;
                v58 = v49[1].m_csEnemy.m_cs.LockCount;
                v55 = v4->m_pOwner;
        LABEL_39:
                v29 = functor->vfptr;
                goto LABEL_40;
                     (v29->onCreature)(v4, t, v55, v58);
                    return;
 
            }
            if (this.m_SkillBase.target == 31 )
            {
                v30 = pTarget;
                if ( !pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[2].GetHandle(pTarget)
                  || !pTarget->baseclass_0.baseclass_0.bIsInWorld )
                {
                    if ( !(pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget)
                      || (v31 = pTarget[1].m_csEnemy.m_cs.DebugInfo) == 0
                      || !LOBYTE(v31[2].CriticalSection) )
                        return;
                    v30 = pTarget[1].m_csEnemy.m_cs.DebugInfo;
                }
                pSummon = v30;
                if ( !v30
                  || (v32 = 12 * v4->m_pSkillBase->valid_range,
                      v33 = (v30 + 108),
                      LODWORD(pos.x) = *v33,
                      v33 += 4,
                      LODWORD(v69) = v32,
                      LODWORD(pos.y) = *v33,
                      v33 += 4,
                      v69 = v32,
                      LODWORD(pos.z) = *v33,
                      v68 = v69,
                      LODWORD(pos.face) = *(v33 + 4),
                      v34 = ArPosition::GetDistance(&pos, &pTarget->baseclass_0.baseclass_0.mv.baseclass_0),
                      v34 > v68) )
                    return;
                v58 = pSummon;
                goto LABEL_38;
            }
            if (this.m_SkillBase.target == 1 )
                goto LABEL_41;
            if (this.m_SkillBase.target <= 1 )
                return;
            if (this.m_SkillBase.target <= 4 )
            {
                if ( !pTarget )
                    return;
                v58 = pTarget;
        LABEL_38:
                v55 = v4->m_pOwner;
                goto LABEL_39;
         LABEL_39:
                v29 = functor->vfptr;
                goto LABEL_40;
 
            }
            if (this.m_SkillBase.target == 6 )
            {
        LABEL_41:
                if ( v5->target == 6 && pTarget == v4->m_pOwner )
                    return;
                if ( v5->is_need_target )
                {
                    if ( !pTarget )
                        return;
                    v59 = pTarget;
                    v56 = v4->m_pOwner;
                }
                else
                {
                    v59 = v4->m_pOwner;
                    v56 = v4->m_pOwner;
                }
                goto LABEL_47;
            }
            if (this.m_SkillBase.target == 21 )
            {
                if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
                  || !(pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget)
                  || (v24 = v4->m_pOwner, v24 != pTarget)
                  && (v25 = *(&v24[1].baseclass_0.m_nRefCount + 1)) != 0
                  && v25 != *(&pTarget[1].baseclass_0.m_nRefCount + 1) )
                    return;
                ::::myPartyFunctor::myPartyFunctor(&fo, v4, t, v24, functor);
                v27 = *(v26 + 4244);
                if ( !v27 )
                {
                    (**v26)(v26);
                    v20 = fo.baseclass_0.vfptr;
                    v21 = &fo;
                    goto LABEL_109;
                }
                v28 = &fo;
        LABEL_111:
                v57 = v28;
                v54 = v27;
                goto LABEL_112;
            }
            if (this.m_SkillBase.target == 22 )
            {
                if ( !(v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)()
                  || !(pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget)
                  || (v17 = v4->m_pOwner, v17 != pTarget)
                  && (v18 = v17[1].quadTreeItem.y) != 0
                  && v18 != pTarget[1].quadTreeItem.y )
                    return;
                ::::myGuildFunctor::myGuildFunctor(&_fo, v4, t, v17, functor);
                if ( *(v19 + 4256) )
                {
                    v22 = *(v19 + 4256);
                    v23 = GuildManager::GetInstance();
                    v15 = GuildManager::DoEachMember(v23, v22, &_fo);
                    goto LABEL_113;
                }
                (**v19)(v19);
                v20 = _fo.vfptr;
                v21 = &_fo;
        LABEL_109:
                (*v20)(v21);
                return;
            }
            if (this.m_SkillBase.target == 23 )
            {
                if ( (v4->m_pOwner->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)() )
                {
                    if ( (pTarget->baseclass_0.baseclass_0.baseclass_0.vfptr[1].onProcess)(pTarget) )
                    {
                        v7 = v4->m_pOwner;
                        if ( v7 == pTarget
                          || (v8 = *(&v7[1].baseclass_0.m_nRefCount + 1)) == 0
                          || v8 == *(&pTarget[1].baseclass_0.m_nRefCount + 1) )
                        {
                            ::::myPartyFunctor::myPartyFunctor(&thisa, v4, t, v7, functor);
                            v9 = *(&v7[1].baseclass_0.m_nRefCount + 1);
                            v10 = *(&v7[1].baseclass_0.m_nRefCount + 1);
                            v11 = PartyManager::GetInstance();
                            v12 = PartyManager::GetAttackTeamLeadPartyID(v11, v10);
                            if ( v12 )
                            {
                                v13 = v12;
                                v14 = PartyManager::GetInstance();
                                v15 = PartyManager::DoEachAttackTeamMember(v14, v13, &thisa.baseclass_0);
        LABEL_113:
                                v4->m_nTargetCount = v15;
                                return;
                            }
                            if ( !v9 )
                            {
                                v16 = v7->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v7);
                                thisa.baseclass_0.vfptr->operator()(&thisa, v16);
                                v4->m_nTargetCount = 1;
                                return;
                            }
                            v57 = &thisa;
                            v54 = v9;
        LABEL_112:
                            v53 = PartyManager::GetInstance();
                            v15 = PartyManager::DoEachMember(v53, v54, v57);
                            goto LABEL_113;
                        }
                    }
                }
            }

*/
        }
// Function       :   protected bool StructSkill::AFFECT_RUSH_OLD(struct StructCreature *, float *, struct ArPosition *, float *)
// Function       :   protected int StructSkill::AFFECT_KNOCK_BACK(struct StructCreature *, float, unsigned long)
// Function       :   protected bool StructSkill::PHYSICAL_DAMAGE_RUSH(struct StructCreature *, int *)
// Function       :   protected void StructSkill::ADD_REGION_STATE(struct StructCreature *)
// Function       :   protected void StructSkill::ADD_STATE_BY_SELF_COST(struct StructCreature *)
// Function       :   protected void StructSkill::ADD_REGION_STATE_BY_SELF_COST(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_DIRECTIONAL_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_T1(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_T2(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_T2_ADD_ENERGY(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T1(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T2(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_T3(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_ABSORB(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_REGION_DAMAGE_OLD(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_MULTIPLE_REGION_DAMAGE_OLD(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_MULTIPLE_SPECIAL_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SPECIAL_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T3(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_PHYSICAL_DAMAGE_T4(struct StructCreature *)
// Function       :   protected bool StructSkill::RUSH(struct StructCreature *, float)
// Function       :   protected bool StructSkill::AFFECT_RUSH(struct StructCreature *, float *, struct ArPosition *, float *, float)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_DAMAGE_ABSORB(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_DAMAGE_ADD_ENERGY(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_REALTIME_MULTIPLE_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_REALTIME_MULTIPLE_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_MULTIPLE_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_MULTIPLE_DAMAGE_TRIPLE_ATTACK(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_MULTIPLE_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::PHYSICAL_SINGLE_SPECIAL_REGION_DAMAGE(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_MAGICAL_DAMAGE_T1(struct StructCreature *)
// Function       :   protected void StructSkill::SINGLE_MAGICAL_DAMAGE_T2(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_MAGICAL_DAMAGE_T1(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_MAGICAL_DAMAGE_T2(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_MAGICAL_DAMAGE_T3(struct StructCreature *)
// Function       :   protected void StructSkill::MULTIPLE_MAGICAL_DAMAGE_AT_ONCE(struct StructCreature *)
// Function       :   protected void StructSkill::MAGIC_SINGLE_REGION_DAMAGE_OLD(struct StructCreature *)
// Function       :   protected void StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_OLD(struct StructCreature *)
// Function       :   protected void StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_T2(struct StructCreature *)
// Function       :   protected void StructSkill::MAGIC_SPECIAL_REGION_DAMAGE_OLD(struct StructCreature *)
// Function       :   protected void StructSkill::MAGIC_ABSORB_DAMAGE(struct StructCreature *)

        protected void SINGLE_MAGICAL_DAMAGE(Creature pTarget)
        {
            if (pTarget != null)
            {
                int magic_point = this.m_Owner.GetMagicPoint((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0);

                int nDamage = (int)(magic_point 
                    * (this.m_SkillBase.m_var[0] + (this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel)) + (this.m_SkillBase.m_var[2] * this.m_nEnhance) 
                    + this.m_SkillBase.m_var[3]
                    + (this.m_SkillBase.m_var[4] * this.m_nRequestedSkillLevel) 
                    + (this.m_SkillBase.m_var[5] * this.m_nEnhance));

                Creature.DamageInfo Damage = pTarget.DealMagicalSkillDamage(this.m_Owner, nDamage, (Elemental.Type)this.m_SkillBase.elemental,
                    this.m_SkillBase.GetHitBonus(this.m_nEnhance, this.m_Owner.GetLevel() - pTarget.GetLevel()),
                    this.m_SkillBase.critical_bonus + (this.m_nRequestedSkillLevel * this.m_SkillBase.critical_bonus_per_skl),0);

                GameContent.AddSkillDamageResult(this.m_vResultList, 1, this.m_SkillBase.elemental, Damage, pTarget.m_hHandle);
            }

        }

        protected void MULTIPLE_MAGICAL_DAMAGE(Creature pTarget)
        {
            if (pTarget != null)
            {
                int magicPoint = this.m_Owner.GetMagicPoint((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0);
                magicPoint = (int)(magicPoint * 
                    (this.m_SkillBase.m_var[0] + (this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel)) + (this.m_SkillBase.m_var[2] * this.m_nEnhance)
                    + this.m_SkillBase.m_var[3] + (this.m_SkillBase.m_var[4] * this.m_nRequestedSkillLevel) + (this.m_SkillBase.m_var[5] * this.m_nEnhance));

                if (this.m_nCurrentFire != 0)
                {
                    this.m_nCurrentFire++;
                }
                else
                {
                    this.m_nTotalFire = (int)(this.m_SkillBase.m_var[6] + (this.m_SkillBase.m_var[7] * this.m_nRequestedSkillLevel));
                    this.m_nCurrentFire = 1;
                }

                Creature.DamageInfo Damage = pTarget.DealMagicalSkillDamage(this.m_Owner, magicPoint, (Elemental.Type)this.m_SkillBase.elemental, 
                    this.m_SkillBase.GetHitBonus(this.m_nEnhance, this.m_Owner.GetLevel() - pTarget.GetLevel()), 
                    (this.m_SkillBase.critical_bonus + (this.m_nRequestedSkillLevel * this.m_SkillBase.critical_bonus_per_skl)), 0);
                GameContent.AddSkillDamageResult(this.m_vResultList, 1, this.m_SkillBase.elemental, Damage, pTarget.m_hHandle);

                this.m_nFireTime = (uint)((this.m_SkillBase.m_var[8] * 100) + this.m_nFireTime);
            }

        }
// Function       :   protected void StructSkill::SINGLE_MAGICAL_DAMAGE_OR_DEATH(Creature pTarget)

        protected void SINGLE_MAGICAL_DAMAGE_WITH_ABSORB(Creature pTarget)
        {
            SkillResult skill_result;
            int elemental_type;
            int nMagicPoint;
            Creature.DamageInfo Damage;
            int nDamage;
            int nAddHP;
            int nAddMP;
            
            if (pTarget != null)
            {
                elemental_type = this.m_SkillBase.elemental;
                nMagicPoint = this.m_Owner.GetMagicPoint((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0);
                nDamage = (int)(nMagicPoint * (this.m_SkillBase.m_var[0] + (this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel)) + (this.m_SkillBase.m_var[2] * this.m_nEnhance)
                    + this.m_SkillBase.m_var[3] + (this.m_SkillBase.m_var[4] * this.m_nRequestedSkillLevel) 
                    + (this.m_SkillBase.m_var[5] * this.m_nEnhance));

                Damage = pTarget.DealMagicalSkillDamage(this.m_Owner,nDamage, (Elemental.Type)this.m_SkillBase.elemental,
                    this.m_SkillBase.GetHitBonus(this.m_nEnhance, this.m_Owner.GetLevel() - pTarget.GetLevel()),
                    (this.m_SkillBase.critical_bonus + (this.m_nRequestedSkillLevel * this.m_SkillBase.critical_bonus_per_skl)),0);

                GameContent.AddSkillDamageResult(this.m_vResultList, 1, (byte)elemental_type, Damage, pTarget.m_hHandle);

                nAddHP = (int)(((this.m_SkillBase.m_var[8] * this.m_nEnhance) + (this.m_SkillBase.m_var[6] + (this.m_SkillBase.m_var[7] * this.m_nRequestedSkillLevel))) * Damage.nDamage);
                nAddMP = (int)(((this.m_SkillBase.m_var[11] * this.m_nEnhance) + (this.m_SkillBase.m_var[9] + (this.m_SkillBase.m_var[10] * this.m_nRequestedSkillLevel))) * Damage.nDamage);
                this.m_Owner.AddHP(nAddHP);
                this.m_Owner.AddMP(nAddMP);

                skill_result = new SkillResult();
                skill_result.addHPType = new SkillResult.AddHPType();
                skill_result.type = (int)SkillResult.ResultType.AddHP;
                skill_result.hTarget = this.m_Owner.m_hHandle;
                skill_result.addHPType.type = (int)SkillResult.ResultType.AddHP;
                skill_result.addHPType.hTarget = this.m_Owner.m_hHandle;
                skill_result.addHPType.target_hp = this.m_Owner.m_nHP;
                skill_result.addHPType.nIncHP = nAddHP;

                this.m_vResultList.Add(skill_result);

                skill_result = new SkillResult();
                skill_result.addHPType = new SkillResult.AddHPType();
                skill_result.type = (int)SkillResult.ResultType.AddMP;
                skill_result.hTarget = this.m_Owner.m_hHandle;
                skill_result.addHPType.type = (int)SkillResult.ResultType.AddMP;
                skill_result.addHPType.hTarget = this.m_Owner.m_hHandle;
                skill_result.addHPType.target_hp = (int)this.m_Owner.m_fMP;
                skill_result.addHPType.nIncHP = nAddHP;
                this.m_vResultList.Add(skill_result);
            }

        }
// Function       :   protected void StructSkill::ADD_HP_MP_BY_ABSORB_HP_MP(Creature pTarget)
// Function       :   protected void StructSkill::SINGLE_MAGICAL_TARGET_HP_PERCENT_DAMAGE(Creature pTarget)
// Function       :   protected void StructSkill::SINGLE_MAGICAL_MANABURN(Creature pTarget)
// Function       :   protected void StructSkill::SINGLE_DAMAGE_BY_CONSUMING_TARGETS_STATE(Creature pTarget)

        protected void MAGIC_SINGLE_REGION_DAMAGE(Creature pTarget)
        {
            int nDamage;                                            // -132 -84h
            float targetMax;                                        // -128 -80h
            float distributeType;                                   // -112 -70h
            List<Creature> vTargetList;                             // -104 -68h
            uint t;                                                 // -72  -48h
            float effectLength;                                     // -68  -44h
            int elemental_type;                                     // -60  -3Ch
            int nMagicPoint;                                        // -60  -3Ch
            Creature.DamageInfo Damage;                             // -48  -30h

            vTargetList = new List<Creature>();

            if (pTarget != null)
            {
                if (this.m_SkillBase.effect_type == (int)SkillBase.EffectType.MagicSingleRegionDamageUsingCorpse)
                {
                    if (!pTarget.IsMonster() || pTarget.m_nHP != 0)
                        return;
                    GameContent.RemoveMonsterFromWorld(pTarget as Monster);
                }

                nMagicPoint = this.m_Owner.GetMagicPoint((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0);
                nDamage = (int)(nMagicPoint * ((this.m_SkillBase.m_var[2] * this.m_nEnhance) 
                    + (this.m_SkillBase.m_var[0] +(this.m_SkillBase.m_var[1] * this.m_nRequestedSkillLevel))) + this.m_SkillBase.m_var[3] 
                    + (this.m_SkillBase.m_var[4] * this.m_nRequestedSkillLevel) + (this.m_SkillBase.m_var[5] * this.m_nEnhance));

                elemental_type = this.m_SkillBase.elemental;
                if (this.m_SkillBase.effect_type == 268 )
                {
                    effectLength = this.m_SkillBase.m_var[12]*12;
                    distributeType = this.m_SkillBase.m_var[13];
                    targetMax = this.m_SkillBase.m_var[14];
                }
                else
                {
                    effectLength = this.m_SkillBase.m_var[9]*12;
                    distributeType = this.m_SkillBase.m_var[10];
                    targetMax = this.m_SkillBase.m_var[11];
                }

                this.m_fRange = effectLength;
                t = Globals.GetArTime();
                nDamage = GameContent.EnumSkillTargetsAndCalcDamage(this.m_Owner.GetCurrentPosition(t),this.m_Owner.m_layer,pTarget.GetCurrentPosition(t),
                          true, effectLength, -1, 0.0f, nDamage, true,this.m_Owner,(int)distributeType,(int)targetMax,vTargetList,true);

                this.m_nTargetCount = vTargetList.Count;

                foreach(Creature cr in vTargetList)
                {
                    Damage = cr.DealMagicalSkillDamage(this.m_Owner,nDamage,(Elemental.Type)elemental_type,
                        this.m_SkillBase.GetHitBonus(this.m_nEnhance, this.m_Owner.GetLevel() - cr.GetLevel()),
                        this.m_SkillBase.critical_bonus + this.m_nRequestedSkillLevel *this.m_SkillBase.critical_bonus_per_skl,0);
                    GameContent.AddSkillDamageResult(this.m_vResultList, 1, (byte)elemental_type, Damage, cr.m_hHandle);
                }
            }
        }
// Function       :   protected void StructSkill::MAGIC_SPECIAL_REGION_DAMAGE(Creature pTarget)
// Function       :   protected void StructSkill::SINGLE_PHYSICAL_DAMAGE_WITH_SHIELD(Creature pTarget)
// Function       :   protected void StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE(Creature pTarget)
// Function       :   protected void StructSkill::MAGIC_MULTIPLE_REGION_DAMAGE_AT_ONCE(Creature pTarget)
// Function       :   protected void StructSkill::MAGIC_SINGLE_REGION_PERCENT_DAMAGE(Creature pTarget)
// Function       :   protected void StructSkill::MAGIC_SINGLE_REGION_DAMAGE_BY_SUMMON_DEAD(Creature pTarget)
// Function       :   protected void StructSkill::REGION_TAUNT(Creature pTarget)
// Function       :   protected void StructSkill::TAUNT(Creature pTarget)
// Function       :   protected void StructSkill::REMOVE_HATE(Creature pTarget)
// Function       :   protected void StructSkill::REGION_REMOVE_HATE(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_RESURRECTION(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_RESURRECTION_WITH_RECOVER(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_ADD_HP_MP(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_ADD_REGION_HP_MP(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_ADD_REGION_HP(Creature pTarget)
// Function       :   protected void StructSkill::SKILL_ADD_REGION_MP(Creature pTarget)
// Function       :   protected void StructSkill::CREATE_ITEM(struct StructCreature *, bool)

        protected void ACTIVATE_FIELD_PROP()
        {
            FieldProp fp = GameObject.get(this.m_hTarget) as FieldProp;
            if (fp != null)
            {
                GameContent.AddSkillResult(this.m_vResultList, fp.UseProp(this.m_Owner as Player), 0, 0);
            }
        }
// Function       :   protected void StructSkill::REGION_HEAL_BY_FIELD_PROP()
// Function       :   protected void StructSkill::MAKE_AREA_EFFECT_PROP_BY_FIELD_PROP(bool)

        protected void CREATURE_TAMING(Creature pTarget)
        {
            if (pTarget != null && pTarget.IsMonster() && this.m_Owner.IsPlayer())
            {
                bool bResult = GameContent.SetTamer(pTarget as Monster, this.m_Owner as Player, this.m_nRequestedSkillLevel);
                if ( bResult )
                {
                    Monster mob = pTarget as Monster;
                    mob.AddHate(this.m_Owner.m_hHandle, 1, true, true);
                }
                GameContent.AddSkillResult(this.m_vResultList, bResult, 0, 0);
            }
        }

// Function       :   protected void StructSkill::PET_TAMING(Creature pTarget)
// Function       :   protected void StructSkill::SHOVELING()

        protected void TOWN_PORTAL()
        {
            ArPosition pos;
            byte layer;

            if (this.m_Owner.IsPlayer())
            {
                Player pPlayer = this.m_Owner as Player;

                pos = pPlayer.GetLastTownPosition();
                layer = 0;

                int cc = ChannelManager.GetChannelId(pPlayer.mv.x, pPlayer.mv.y);
                int nc = ChannelManager.GetChannelId(pos.x, pos.y);
                if (cc != 0 && cc == nc)
                {
                    layer = pPlayer.m_layer;
                }
                else if (nc != 0)
                {
                    layer = ChannelManager.GetProperLayer(pos.x, pos.y);
                }

                pPlayer.PendWarp((int)pos.x, (int)pos.y, layer);
                pos = pPlayer.GetCurrentPosition(Globals.GetArTime());
                pPlayer.SetMove(pos, 0,0);
                RappelzServer.Instance.SetObjectPriority(pPlayer, SchedulerObject.Priority.Highest);
            }
        }
// Function       :   protected void StructSkill::RETURN_FEATHER()
// Function       :   protected void StructSkill::RETURN_BACK_FEATHER()
// Function       :   protected void StructSkill::TOGGLE_AURA(Creature pTarget)

        protected void MAKE_AREA_EFFECT_PROP(Creature pTarget, bool bIsTrap)
        {
// .text:004D35E2 var_28          = dword ptr -28h
// .text:004D35E2 var_24          = dword ptr -24h
            ArPosition pos;//             = ArPosition ptr -14h
            bool bPhysical;//       = byte ptr -4
            float fHateRatio;//      = dword ptr  8

//            .text:004D35E2 bIsTrap         = byte ptr  0Ch
//            v3 = this;
            if (pTarget != null)
            {
                if (bIsTrap)
                {
                    uint trapId = this.m_Owner.GetTrapHandle();
                    if (trapId != 0)
                    {
                        SkillProp trap = GameObject.raw_get(trapId) as SkillProp;
                        if (trap != null)
                            trap.PendRemove();
                    }
                }
                uint ct = Globals.GetArTime();
                pos = pTarget.GetCurrentPosition(Globals.GetArTime() + 200);
                int nMagicPoint = this.m_Owner.GetMagicPoint((Elemental.Type)this.m_SkillBase.elemental, this.m_SkillBase.is_spell_act == 0, this.m_SkillBase.is_harmful != 0);

                fHateRatio = this.m_Owner.m_fHateRatio;
                SkillProp sProp = SkillProp.Create(this.m_Owner.m_hHandle, this, nMagicPoint, fHateRatio);

                if ( bIsTrap )
                {
                    if (sProp != null)
                        this.m_Owner.m_hTrap = sProp.m_hHandle;
                }
                sProp.SetCurrentXY(pos.x, pos.y);
                sProp.m_layer = this.m_Owner.m_layer;
                RappelzServer.Instance.AddObject(sProp);
                RappelzServer.Instance.SetObjectPriority(sProp, SchedulerObject.Priority.High);
            }
        }
// Function       :   protected void StructSkill::CORPSE_ABSORB(Creature pTarget)
// Function       :   protected void StructSkill::CORPSE_EXPLOSION(Creature pTarget)
// Function       :   protected void StructSkill::ADD_ENERGY()
// Function       :   protected void StructSkill::CASTING_CANCEL_WITH_ADD_STATE(Creature pTarget)

        protected void RESPAWN_NEAR_MONSTER()
        {
            ArPosition targetPos;           // -88  -58h
            ArPosition pos;                 // -72  -48h
            int nMonsterID;                 // -24  -18h
            float x = 0;                        // -16  -10h
            float y = 0;                        // -12  -0Ch
            bool bShareEnemyOnRespawn;      //= byte ptr -1
            uint ct;

            if (this.m_Owner.IsMonster())
            {
                ct = Globals.GetArTime();
                pos = this.m_Owner.GetCurrentPosition(ct);
                if (!GameContent.IsBlocked(pos.x, pos.y))
                {
                    for (int i = 0; i < 3;++i)
                    {
                        nMonsterID = (int)this.m_SkillBase.m_var[(i*3)];
                        int share = (int)this.m_SkillBase.m_var[(i*3) + 2];
                        int mobCount = (int)this.m_SkillBase.m_var[(i*3) + 1];
                        bShareEnemyOnRespawn = true;
                        if (share == 0)
                            bShareEnemyOnRespawn = false;
                        for (int mc = 0; mc < mobCount; ++mc)
                        {
                            Monster mob = GameContent.respawnMonster((uint)pos.x, (uint)pos.y, this.m_Owner.m_layer, (uint)nMonsterID, true, 0, null, false);
                            for (int v = 0; v < 300; ++v)
                            {
                                x = Globals.GetRandomInt32((int)(pos.x - 60), (int)(pos.y + 60));
                                y = Globals.GetRandomInt32((int)(pos.x - 60), (int)(pos.y + 60));
                                if (!GameContent.IsBlocked(x, y))
                                {
                                    targetPos = new ArPosition(x, y, 0);
                                    mob.SetMove(targetPos, (byte)(3 * mob.GetMoveSpeed() / 7), 0);
                                    break;
                                }
                            }
                            mob.m_bRespawnByScript = true;
                            Monster ownerMob = this.m_Owner as Monster;

                            RappelzServer.Instance.SetObjectPriority(mob, SchedulerObject.Priority.Highest);
                            if (ownerMob.m_bIsDungeonRaidMonster)
                            {
                                int nDungeonID = DungeonManager.Instance.GetDungeonID(x, y);
                                if (nDungeonID != 0)
                                {
                                    mob.m_bIsDungeonRaidMonster = true;
                                    mob.CalculateStat();
                                    //                                         LOBYTE(v21) = v1->m_pOwner->baseclass_0.baseclass_0.layer;
                                    //                                         v16 = v21;
                                    //                                         v17 = DungeonManager::Instance();
                                    //                                         DungeonManager::AddToDungeonRaidMonster(v17, v8, v15, v16);
                                }
                            }
                            if (bShareEnemyOnRespawn)
                            {
                                if (ownerMob.m_hEnemy != 0)
                                    mob.AddHate(ownerMob.m_hEnemy, 1, true, true);
                            }
                        }
                    }
                    GameContent.AddSkillResult(this.m_vResultList, true, 0, 0);
                }
            }

        }

        protected void SUMMON_SCROLL()
        {
            ArPosition targetPos;           // -88  -58h
            ArPosition pos;                 // -72  -48h
            int nMonsterID;                 // -24  -18h
            float x = 0;                        // -16  -10h
            float y = 0;                        // -12  -0Ch
            bool bShareEnemyOnRespawn;      //= byte ptr -1
            uint ct;

            if (this.m_Owner.IsPlayer())
            {
                ct = Globals.GetArTime();
                pos = this.m_Owner.GetCurrentPosition(ct);
                if (!GameContent.IsBlocked(pos.x, pos.y))
                {
                    nMonsterID = (int)this.m_SkillBase.m_var[this.m_nRequestedSkillLevel-1];
                    Monster mob = GameContent.respawnMonster((uint)pos.x, (uint)pos.y, this.m_Owner.m_layer, (uint)nMonsterID, true, 0, null, false);
                    mob.SetMove(pos, 0, 0);
                    for (int v = 0; v < 300; ++v)
                    {
                        x = Globals.GetRandomInt32((int)(pos.x - 60), (int)(pos.x + 60));
                        y = Globals.GetRandomInt32((int)(pos.y - 60), (int)(pos.y + 60));
                        if (!GameContent.IsBlocked(x, y))
                        {
                            targetPos = new ArPosition(x, y, 0);
                            mob.SetMove(targetPos, (byte)(3 * mob.GetMoveSpeed() / 7), 0);
                            break;
                        }
                    }
                    mob.m_bRespawnByScript = true;
                    GameContent.AddSkillResult(this.m_vResultList, true, 0, 0);
                }
            }

        }

        protected void Summon()
        {
            Item pItem = Item.FindItem(this.m_hTarget);
            if (pItem != null)
            {
                if (pItem.m_pItemBase.nGroup == 13)
                {
                    Summon pSummon = pItem.m_pSummon;
                    if (pSummon != null)
                    {
                        if (pSummon.m_master.m_hHandle == this.m_Owner.m_hHandle)
                        {
                            if (!pSummon.bIsInWorld)
                            {
                                Player p = this.m_Owner as Player;
                                p.Summon(pSummon, this.m_targetPos);
                            }
                        }
                    }
                }
            }

        }

        protected void UnSummon()
        {
            Player p = this.m_Owner as Player;
            if (this.m_Owner.IsPlayer())
            {
                Item item = Item.FindItem(this.m_hTarget);
                if (item != null)
                {
                    if (item.m_pItemBase.nGroup == 13 )
                    {
                        if (item.m_pSummon != null)
                        {
                            if (item.m_pSummon.m_master.m_hHandle == this.m_Owner.m_hHandle)
                                p.UnSummon(item.m_pSummon);
                        }
                    }
                }
            }
        }
// Function       :   protected void StructSkill::UnSummonAndAddState()
// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0xFF, Constant, Type: int, SKILL_UID_ITEM_SKILL
// Data           :     constant 0xFE, Constant, Type: int, SKILL_UID_PROP_SKILL
// Data           :     constant 0xFD, Constant, Type: int, SKILL_UID_MONSTER_SKILL
// Data           :     constant 0xFC, Constant, Type: int, SKILL_UID_SUMMON_SKILL
// Data           :     constant 0xFB, Constant, Type: int, SKILL_UID_PET_SKILL
// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0x43A, Constant, Type: int, SKILL_INCREASE_ENERGY
// Data           :     constant 0x49D, Constant, Type: int, SKILL_DUAL_SWORD_EXPERT
// Data           :     constant 0x4B1, Constant, Type: int, SKILL_ARMOR_MASTERY
// Data           :     constant 0x409, Constant, Type: int, SKILL_LIFE_OF_DARKNESS
// Data           :     constant 0x709, Constant, Type: int, SKILL_CREATURE_CONTROL
// Data           :     constant 0x713, Constant, Type: int, SKILL_CREATURE_MASTERY
// Data           :     constant 0x759, Constant, Type: int, SKILL_TECHNICAL_CREATURE_CONTROL
// Data           :     constant 0x3FE, Constant, Type: int, SKILL_ADV_WEAPON_EXPERT
// Data           :     constant 0x4B2, Constant, Type: int, SKILL_GAIA_ARMOR_MASTERY
// Data           :     constant 0x2AFA, Constant, Type: int, SKILL_RAISE_EXP
// Data           :     constant 0x2AFB, Constant, Type: int, SKILL_RAISE_JP
// Data           :     constant 0xA47, Constant, Type: int, SKILL_GAIA_FORCE_SAVING
// Data           :     constant 0x1771, Constant, Type: int, SKILL_ITEM_RESURRECTION_SCROLL
// Data           :     constant 0x1772, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL
// Data           :     constant 0x1773, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL
// Data           :     constant 0x1774, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL
// Data           :     constant 0x1775, Constant, Type: int, SKILL_ITEM_ANTIDOTE_SCROLL
// Data           :     constant 0x1776, Constant, Type: int, SKILL_ITEM_RECHARGE_SCROLL
// Data           :     constant 0x1777, Constant, Type: int, SKILL_TOWN_PORTAL
// Data           :     constant 0xEDA, Constant, Type: int, SKILL_RETURN
// Data           :     constant 0x1778, Constant, Type: int, SKILL_FORCE_CHIP
// Data           :     constant 0x1779, Constant, Type: int, SKILL_SOUL_CHIP
// Data           :     constant 0x177A, Constant, Type: int, SKILL_LUNA_CHIP
// Data           :     constant 0x177D, Constant, Type: int, SKILL_ITEM_PERFECT_CREATURE_RESURRECTION_SCROLL
// Data           :     constant 0x177E, Constant, Type: int, SKILL_ITEM_PIECE_OF_STRENGTH
// Data           :     constant 0x177F, Constant, Type: int, SKILL_ITEM_PIECE_OF_VITALITY
// Data           :     constant 0x1780, Constant, Type: int, SKILL_ITEM_PIECE_OF_DEXTERITY
// Data           :     constant 0x1781, Constant, Type: int, SKILL_ITEM_PIECE_OF_AGILITY
// Data           :     constant 0x1782, Constant, Type: int, SKILL_ITEM_PIECE_OF_INTELLIGENCE
// Data           :     constant 0x1783, Constant, Type: int, SKILL_ITEM_PIECE_OF_MENTALITY
// Data           :     constant 0x1784, Constant, Type: int, SKILL_RETURN_FEATHER
// Data           :     constant 0x1785, Constant, Type: int, SKILL_RETURN_BACK_FEATHER
// Data           :     constant 0xFFFFFD29, Constant, Type: int, SKILL_FIRE_BOMB_PHYSICAL
// Data           :     constant 0xFFFFFD2A, Constant, Type: int, SKILL_FIRE_BOMB_MAGICAL
// Data           :     constant 0x1786, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV1
// Data           :     constant 0x1787, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV2
// Data           :     constant 0x1788, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV3
// Data           :     constant 0x1789, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV4
// Data           :     constant 0x178A, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV5
// Data           :     constant 0x178B, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV6
// Data           :     constant 0x178C, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV7
// Data           :     constant 0x178D, Constant, Type: int, SKILL_ITEM_REGENERATION_SCROLL_LV8
// Data           :     constant 0x178E, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV1
// Data           :     constant 0x178F, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV2
// Data           :     constant 0x1790, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV3
// Data           :     constant 0x1791, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV4
// Data           :     constant 0x1792, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV5
// Data           :     constant 0x1793, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV6
// Data           :     constant 0x1794, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV7
// Data           :     constant 0x1795, Constant, Type: int, SKILL_ITEM_HEALING_SCROLL_LV8
// Data           :     constant 0x1796, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV1
// Data           :     constant 0x1797, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV2
// Data           :     constant 0x1798, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV3
// Data           :     constant 0x1799, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV4
// Data           :     constant 0x179A, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV5
// Data           :     constant 0x179B, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV6
// Data           :     constant 0x179C, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV7
// Data           :     constant 0x179D, Constant, Type: int, SKILL_ITEM_MANA_RECOVERY_SCROLL_LV8
// Data           :     constant 0x179E, Constant, Type: int, SKILL_CALL_BLACK_PINE_TEA
// Data           :     constant 0x179F, Constant, Type: int, SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV1
// Data           :     constant 0x17A0, Constant, Type: int, SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV2
// Data           :     constant 0x17A1, Constant, Type: int, SKILL_ITEM_SUMMON_SPEED_UP_SCROLL_LV3
// Data           :     constant 0x17AD, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_STRENGTH
// Data           :     constant 0x17AE, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_VITALITY
// Data           :     constant 0x17AF, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_DEXTERITY
// Data           :     constant 0x17B0, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_AGILITY
// Data           :     constant 0x17B1, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_INTELLIGENCE
// Data           :     constant 0x17B2, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_MENTALITY
// Data           :     constant 0x17B3, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_STRENGTH_QUEST
// Data           :     constant 0x17B4, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_VITALITY_QUEST
// Data           :     constant 0x17B5, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_DEXTERITY_QUEST
// Data           :     constant 0x17B6, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_AGILITY_QUEST
// Data           :     constant 0x17B7, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_INTELLIGENCE_QUEST
// Data           :     constant 0x17B8, Constant, Type: int, SKILL_ITEM_ALTERED_PIECE_OF_MENTALITY_QUEST
// Data           :     constant 0x1AF5, Constant, Type: int, SKILL_COLLECTING
// Data           :     constant 0x1AF6, Constant, Type: int, SKILL_MINING
// Data           :     constant 0x1AF7, Constant, Type: int, SKILL_OPERATING
// Data           :     constant 0x1AF8, Constant, Type: int, SKILL_ACTIVATING
// Data           :     constant 0x1AF9, Constant, Type: int, SKILL_OPERATE_DEVICE
// Data           :     constant 0x1AFA, Constant, Type: int, SKILL_OPERATE_DUNGEON_CORE
// Data           :     constant 0x1AFD, Constant, Type: int, SKILL_OPERATE_EXPLORATION
// Data           :     constant 0xFFFFFD26, Constant, Type: int, SKILL_TREE_OF_HEALING_TYPE_A
// Data           :     constant 0xFFFFFD27, Constant, Type: int, SKILL_TREE_OF_HEALING_TYPE_B
// Data           :     constant 0x1AFB, Constant, Type: int, SKILL_SHOVELING
// Data           :     constant 0x1AFC, Constant, Type: int, SKILL_PET_TAMING
// Data           :     constant 0xFA3, Constant, Type: int, SKILL_CREATURE_TAMING
// Data           :     constant 0x2719, Constant, Type: int, SKILL_THROW_SMALL_SNOWBALL
// Data           :     constant 0x271A, Constant, Type: int, SKILL_THROW_BIG_SNOWBALL
// Data           :     constant 0x2AF9, Constant, Type: int, SKILL_CREATURE_RIDING
// Data           :     constant 0x2EE1, Constant, Type: int, SKILL_UNIT_EXPERT_LV2
// Data           :     constant 0x2EE2, Constant, Type: int, SKILL_UNIT_EXPERT_LV3
// Data           :     constant 0x2EE3, Constant, Type: int, SKILL_UNIT_EXPERT_LV4
// Data           :     constant 0x2EE4, Constant, Type: int, SKILL_UNIT_EXPERT_LV5
// Data           :     constant 0x2EE5, Constant, Type: int, SKILL_UNIT_EXPERT_LV6
// Data           :     constant 0x36B1, Constant, Type: int, SKILL_AMORY_UNIT
// Data           :     constant 0xFFFFEE52, Constant, Type: int, SKILL_TWIN_BLADE_EXPERT
// Data           :     constant 0xFFFFEE57, Constant, Type: int, SKILL_TWIN_AXE_EXPERT
// Data           :     constant 0xFFFFFD28, Constant, Type: int, SKILL_NEW_YEAR_CHAMPAGNE
// Data           :     constant 0xFFFFFD2D, Constant, Type: int, SKILL_NAMUIR_LEAF_POISON
// Data           :     constant 0xFFFFFD2E, Constant, Type: int, SKILL_NAMUIR_RIND_BLEEDING
// Function       :   public struct StructSkill & operator=(const struct StructSkill &)
// Function       :   public void * __vecDelDtor(unsigned int)

    }
}
